{"ts": "2026-07-17T14:52:19.095327+00:00", "type": "system_prompt", "text": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}
{"ts": "2026-07-17T14:52:19.095835+00:00", "type": "user", "text": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}
{"ts": "2026-07-17T14:53:26.342129+00:00", "type": "llm_call", "call_index": 1, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:52:19.095835+00:00", "finished_at": "2026-07-17T14:53:26.329704+00:00", "duration_s": 67.23399999999674, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:52:19.095835+00:00", "finished_at": "2026-07-17T14:53:26.328701+00:00", "duration_s": 67.23399999999674, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "21324", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:52:21 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784299939-2eH1flMuUUexphUDXOYZ", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca11dee957cfc6-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784299939-2eH1flMuUUexphUDXOYZ\",\"object\":\"chat.completion\",\"created\":1784299939,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"refusal\":null,\"reasoning\":\"Let me think about this task carefully.\\n\\nThis is a complex Blender still life scene that needs to:\\n1. Reference the Dutch Golden Age still life painting tradition\\n2. Feature CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, checkered sphere\\n3. Include a classical prop (fruit, candlestick, book, or wine glass)\\n4. Cornell box palette nod (red and green elements facing each other, neutral white/grey between)\\n5. Chiaroscuro lighting (single warm dominant light, deep shadows, dark background)\\n6. Specific materials for each object\\n7. Composition with table edge, overlapping depth, teapot as hero, 50mm equivalent camera\\n\\nLet me plan this out:\\n\\n**Scene setup:**\\n- Dark background (maybe deep brown/black walls)\\n- A table with a draped cloth\\n- Cornell nod: red cloth on one side, green cloth on other, with neutral white/grey between\\n\\n**Objects to model:**\\n1. Utah Teapot - the classic squat teapot with spout, handle, lid. Ceramic or silver material.\\n2. Stanford Bunny - crouched rabbit silhouette with rounded back and folded ears\\n3. Suzanne - Blender's monkey head, mounted as a bust\\n4. Reflective checkered sphere - polished chrome with checkered pattern\\n5. Supporting prop - I'll go with a wine glass or some fruit (lemon, grapes)\\n\\n**Lighting:**\\n- Single warm light from one side (like a window shaft)\\n- Dark background\\n- Chiaroscuro effect\\n\\n**Camera:**\\n- 50mm equivalent, slightly elevated angle\\n\\nLet me start by exploring the current scene state, then build this step by step.\\n\\nLet me begin by setting up the scene. I'll work in stages:\\n\\n1. First, set up the basic scene - clear default objects, set up world/background\\n2. Build the table and drapery (with Cornell red/green/white palette)\\n3. Model the Utah Teapot\\n4. Model the Stanford Bunny\\n5. Add Suzanne (built-in)\\n6. Create the checkered reflective sphere\\n7. Add a supporting prop (wine glass with red wine, or a lemon)\\n8. Set up lighting (warm shaft of light from side)\\n9. Set up camera (50mm equivalent, slightly elevated)\\n10. Material tweaks and final composition\\n11. Render and verify\\n\\nLet me start with checking the current scene state.\\n\\nActually, let me think about the materials more carefully:\\n\\n- Utah Teapot: silver or ceramic. I'll go with a pewter/silver material - that's very Dutch Golden Age.\\n- Stanford Bunny: maybe a bronze or marble sculpture material\\n- Suzanne: as a bust - maybe mounted on a small pedestal, bronze or marble\\n- Checkered sphere: polished chrome with checkered pattern (classic ray tracing)\\n- Wine glass: glass material with red wine\\n- Cloth: velvet-dark with folds\\n\\nFor the Cornell nod:\\n- Red cloth draped on one side\\n- Green cloth or wall panel on the other\\n- White/grey tablecloth or background between\\n\\nLet me think about composition:\\n- Table edge in lower frame\\n- Teapot as hero - center-ish, commanding\\n- Objects grouped with overlapping depth\\n- Slightly elevated angle\\n\\nLet me start building. I'll begin with a clean scene and set up the environment.\\n\\nLet me start coding.\\n\\nActually, I should plan the materials approach for the checkered sphere. A \\\"reflective checkered sphere\\\" is the classic ray tracing demo. I can do this with a checker texture on a glossy material - the checker pattern would be visible on the sphere surface and it would be reflective.\\n\\nLet me think about the Utah Teapot. I need to model this from scratch. The Utah teapot has:\\n- A squashed sphere body\\n- A spout (curved)\\n- A handle (curved, like a torus segment)\\n- A lid with a small knob\\n\\nI can model this using bezier curves and bevels, or build it from primitives. Let me think...\\n\\nActually, the best approach for the teapot might be to use a combination of:\\n- A UV sphere squashed for the body\\n- A bezier curve for the spout, beveled with a circle\\n- A bezier curve for the handle, beveled with a circle\\n- A smaller flattened sphere for the lid\\n- A small sphere for the knob\\n\\nFor the Stanford Bunny, I need to approximate the silhouette. The bunny has:\\n- A rounded body/back\\n- A head\\n- Folded ears\\n- It's quite compact and crouched\\n\\nI could sculpt this or build it from primitives. Let me try building from primitives and then using sculpt mode or just careful modeling.\\n\\nActually, let me use metaballs or careful primitive combination for the bunny, then maybe sculpt a bit.\\n\\nLet me start with the scene setup.\\n\\nLet me first get the current state.\\n\\nI'll start with executing code to set up the scene. Let me plan the first batch of operations:\\n\\n1. Clear the default scene\\n2. Set up render settings (Cycles, color management)\\n3. Set up the world (dark background)\\n\\nThen I'll build the environment (table, cloths, walls), then the objects.\\n\\nLet me begin.\\n\\nActually, I realize I should be strategic about my tool calls. Each code execution can do a lot. Let me write comprehensive scripts for each stage.\\n\\nStage 1: Scene setup - clear defaults, set render settings, set up world\\nStage 2: Build environment - table, back wall, drapery (Cornell colors)\\nStage 3: Model Utah Teapot\\nStage 4: Model Stanford Bunny\\nStage 5: Add Suzanne as bust\\nStage 6: Create checkered reflective sphere\\nStage 7: Add wine glass (supporting prop)\\nStage 8: Materials for everything\\nStage 9: Lighting\\nStage 10: Camera setup\\nStage 11: Preview render and adjust\\n\\nLet me start.\\n\\nActually, let me reconsider the approach. I think I should:\\n1. Build all geometry first\\n2. Then do materials\\n3. Then lighting and camera\\n4. Then iterate on the render\\n\\nBut some things are easier to do together (geometry + material). Let me be pragmatic.\\n\\nLet me start with scene setup and environment.\\n\\nFor the cloth/folds, I could use a plane with subdivision and some displacement, or I could use cloth simulation. Cloth simulation might be complex to control. Let me use a subdivided plane with manual vertex manipulation or a displace modifier with a noise texture to create folds.\\n\\nActually, for the drapery, a good approach is:\\n- Create a plane, subdivide it heavily\\n- Use a Displace modifier with a noise texture for fold structure\\n- Or sculpt it\\n\\nLet me think about what will look best and be most controllable. I think a combination of a subdivided plane with some manual shaping and a noise displacement could work. Or I could use the cloth simulator to drape a cloth over the table edge.\\n\\nLet me try the cloth simulation approach for the main tablecloth - it would give realistic folds. But I need to control it carefully.\\n\\nActually, for reliability, let me use a subdivided mesh with careful vertex manipulation and a noise modifier. This is more predictable than simulation.\\n\\nHmm, let me reconsider. For a Dutch still life, the cloth drapery is important. Let me use a subdivided plane and sculpt/shape it manually with code (moving vertices), plus a noise displacement for fine fold detail.\\n\\nLet me start coding.\\n\\nLet me think about the overall scene layout:\\n\\n- Table: a box, roughly 2m wide, 1m deep, at height ~0.75m\\n- Back wall: dark, maybe 3m behind the table\\n- Tablecloth: draping over the table, white/grey neutral\\n- Red cloth: draped on the left side\\n- Green cloth or wall panel: on the right side\\n\\nObjects on the table (from camera's perspective):\\n- Teapot: center, slightly left, hero\\n- Bunny: behind teapot, slightly right\\n- Suzanne: on a small pedestal, right side\\n- Checkered sphere: front left\\n- Wine glass: right side, with red wine\\n\\nCamera: slightly elevated, ~50mm equivalent, looking at the arrangement\\n\\nLight: warm light from the left (window shaft), maybe a spot light or area light\\n\\nLet me start building.\\n\\nFor the first code block, let me:\\n1. Clear the scene\\n2. Set up Cycles render settings\\n3. Set up the world background (dark)\\n4. Set color management\\n\\nLet me go.\\n\\nActually, I should also think about what \\\"50mm equivalent\\\" means. On a full-frame sensor (36mm x 24mm), a 50mm lens has a horizontal FOV of about 39.6 degrees. In Blender, the default sensor size is 36mm. So I should set the camera focal length to 50mm with a 36mm sensor.\\n\\nLet me start with the scene setup.\\n\\nLet me write my first code block to set up the scene.\\n\\nI'll start simple and build up. Let me clear everything and set up the basics.\\n\\nFor this first step, let me:\\n1. Delete all existing objects\\n2. Set render engine to Cycles\\n3. Set render resolution\\n4. Set color management to Filmic\\n5. Set world to dark\\n\\nLet me go.\\n\\nI think I should also plan the materials. Let me think about what shaders I'll need:\\n\\n1. Silver/pewter teapot: Principled BSDF, high metallic, roughness ~0.3-0.4, slightly tinted\\n2. Bronze bunny: Principled BSDF, metallic, copper/bronze color\\n3. Marble Suzanne: Principled BSDF, white/grey, low roughness, maybe subsurface\\n4. Checkered chrome sphere: Glossy BSDF with checker texture (mix of two colors, one reflective)\\n5. Wine glass: Glass BSDF\\n6. Wine: dark red, slightly transparent\\n7. Velvet cloth: Principled BSDF with sheen, or a velvet shader\\n8. Wood table: Principled BSDF with wood texture\\n9. Wall: dark, slightly textured\\n\\nLet me start building. I'll do the environment first.\\n\\nLet me write the code for scene setup and environment.\\n\\nI'll think about this more carefully as I go. Let me start.\\n\\nLet me think about the dimensions. I'll use a scale where the table is about 1.5m wide.\\n\\nTable: 1.5m x 0.8m, height 0.75m\\nTeapot: about 0.2m tall\\nBunny: about 0.15m tall\\nSuzanne: default size, about 0.2m\\nSphere: 0.1m radius\\nWine glass: about 0.2m tall\\n\\nCamera: about 1.2m high, 1m back from table edge, looking at the arrangement\\n\\nLet me start coding now. I'll do the scene setup first.\\n\\nLet me think step by step about what to do first:\\n\\n1. Clear scene\\n2. Set up render settings (Cycles, Filmic, etc.)\\n3. Build the environment: table, walls, cloth\\n4. Build each object\\n5. Apply materials\\n6. Set up lighting\\n7. Set up camera\\n8. Preview render and iterate\\n\\nLet me begin with step 1-2.\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"type\":\"function\",\"index\":1,\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"Let me think about this task carefully.\\n\\nThis is a complex Blender still life scene that needs to:\\n1. Reference the Dutch Golden Age still life painting tradition\\n2. Feature CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, checkered sphere\\n3. Include a classical prop (fruit, candlestick, book, or wine glass)\\n4. Cornell box palette nod (red and green elements facing each other, neutral white/grey between)\\n5. Chiaroscuro lighting (single warm dominant light, deep shadows, dark background)\\n6. Specific materials for each object\\n7. Composition with table edge, overlapping depth, teapot as hero, 50mm equivalent camera\\n\\nLet me plan this out:\\n\\n**Scene setup:**\\n- Dark background (maybe deep brown/black walls)\\n- A table with a draped cloth\\n- Cornell nod: red cloth on one side, green cloth on other, with neutral white/grey between\\n\\n**Objects to model:**\\n1. Utah Teapot - the classic squat teapot with spout, handle, lid. Ceramic or silver material.\\n2. Stanford Bunny - crouched rabbit silhouette with rounded back and folded ears\\n3. Suzanne - Blender's monkey head, mounted as a bust\\n4. Reflective checkered sphere - polished chrome with checkered pattern\\n5. Supporting prop - I'll go with a wine glass or some fruit (lemon, grapes)\\n\\n**Lighting:**\\n- Single warm light from one side (like a window shaft)\\n- Dark background\\n- Chiaroscuro effect\\n\\n**Camera:**\\n- 50mm equivalent, slightly elevated angle\\n\\nLet me start by exploring the current scene state, then build this step by step.\\n\\nLet me begin by setting up the scene. I'll work in stages:\\n\\n1. First, set up the basic scene - clear default objects, set up world/background\\n2. Build the table and drapery (with Cornell red/green/white palette)\\n3. Model the Utah Teapot\\n4. Model the Stanford Bunny\\n5. Add Suzanne (built-in)\\n6. Create the checkered reflective sphere\\n7. Add a supporting prop (wine glass with red wine, or a lemon)\\n8. Set up lighting (warm shaft of light from side)\\n9. Set up camera (50mm equivalent, slightly elevated)\\n10. Material tweaks and final composition\\n11. Render and verify\\n\\nLet me start with checking the current scene state.\\n\\nActually, let me think about the materials more carefully:\\n\\n- Utah Teapot: silver or ceramic. I'll go with a pewter/silver material - that's very Dutch Golden Age.\\n- Stanford Bunny: maybe a bronze or marble sculpture material\\n- Suzanne: as a bust - maybe mounted on a small pedestal, bronze or marble\\n- Checkered sphere: polished chrome with checkered pattern (classic ray tracing)\\n- Wine glass: glass material with red wine\\n- Cloth: velvet-dark with folds\\n\\nFor the Cornell nod:\\n- Red cloth draped on one side\\n- Green cloth or wall panel on the other\\n- White/grey tablecloth or background between\\n\\nLet me think about composition:\\n- Table edge in lower frame\\n- Teapot as hero - center-ish, commanding\\n- Objects grouped with overlapping depth\\n- Slightly elevated angle\\n\\nLet me start building. I'll begin with a clean scene and set up the environment.\\n\\nLet me start coding.\\n\\nActually, I should plan the materials approach for the checkered sphere. A \\\"reflective checkered sphere\\\" is the classic ray tracing demo. I can do this with a checker texture on a glossy material - the checker pattern would be visible on the sphere surface and it would be reflective.\\n\\nLet me think about the Utah Teapot. I need to model this from scratch. The Utah teapot has:\\n- A squashed sphere body\\n- A spout (curved)\\n- A handle (curved, like a torus segment)\\n- A lid with a small knob\\n\\nI can model this using bezier curves and bevels, or build it from primitives. Let me think...\\n\\nActually, the best approach for the teapot might be to use a combination of:\\n- A UV sphere squashed for the body\\n- A bezier curve for the spout, beveled with a circle\\n- A bezier curve for the handle, beveled with a circle\\n- A smaller flattened sphere for the lid\\n- A small sphere for the knob\\n\\nFor the Stanford Bunny, I need to approximate the silhouette. The bunny has:\\n- A rounded body/back\\n- A head\\n- Folded ears\\n- It's quite compact and crouched\\n\\nI could sculpt this or build it from primitives. Let me try building from primitives and then using sculpt mode or just careful modeling.\\n\\nActually, let me use metaballs or careful primitive combination for the bunny, then maybe sculpt a bit.\\n\\nLet me start with the scene setup.\\n\\nLet me first get the current state.\\n\\nI'll start with executing code to set up the scene. Let me plan the first batch of operations:\\n\\n1. Clear the default scene\\n2. Set up render settings (Cycles, color management)\\n3. Set up the world (dark background)\\n\\nThen I'll build the environment (table, cloths, walls), then the objects.\\n\\nLet me begin.\\n\\nActually, I realize I should be strategic about my tool calls. Each code execution can do a lot. Let me write comprehensive scripts for each stage.\\n\\nStage 1: Scene setup - clear defaults, set render settings, set up world\\nStage 2: Build environment - table, back wall, drapery (Cornell colors)\\nStage 3: Model Utah Teapot\\nStage 4: Model Stanford Bunny\\nStage 5: Add Suzanne as bust\\nStage 6: Create checkered reflective sphere\\nStage 7: Add wine glass (supporting prop)\\nStage 8: Materials for everything\\nStage 9: Lighting\\nStage 10: Camera setup\\nStage 11: Preview render and adjust\\n\\nLet me start.\\n\\nActually, let me reconsider the approach. I think I should:\\n1. Build all geometry first\\n2. Then do materials\\n3. Then lighting and camera\\n4. Then iterate on the render\\n\\nBut some things are easier to do together (geometry + material). Let me be pragmatic.\\n\\nLet me start with scene setup and environment.\\n\\nFor the cloth/folds, I could use a plane with subdivision and some displacement, or I could use cloth simulation. Cloth simulation might be complex to control. Let me use a subdivided plane with manual vertex manipulation or a displace modifier with a noise texture to create folds.\\n\\nActually, for the drapery, a good approach is:\\n- Create a plane, subdivide it heavily\\n- Use a Displace modifier with a noise texture for fold structure\\n- Or sculpt it\\n\\nLet me think about what will look best and be most controllable. I think a combination of a subdivided plane with some manual shaping and a noise displacement could work. Or I could use the cloth simulator to drape a cloth over the table edge.\\n\\nLet me try the cloth simulation approach for the main tablecloth - it would give realistic folds. But I need to control it carefully.\\n\\nActually, for reliability, let me use a subdivided mesh with careful vertex manipulation and a noise modifier. This is more predictable than simulation.\\n\\nHmm, let me reconsider. For a Dutch still life, the cloth drapery is important. Let me use a subdivided plane and sculpt/shape it manually with code (moving vertices), plus a noise displacement for fine fold detail.\\n\\nLet me start coding.\\n\\nLet me think about the overall scene layout:\\n\\n- Table: a box, roughly 2m wide, 1m deep, at height ~0.75m\\n- Back wall: dark, maybe 3m behind the table\\n- Tablecloth: draping over the table, white/grey neutral\\n- Red cloth: draped on the left side\\n- Green cloth or wall panel: on the right side\\n\\nObjects on the table (from camera's perspective):\\n- Teapot: center, slightly left, hero\\n- Bunny: behind teapot, slightly right\\n- Suzanne: on a small pedestal, right side\\n- Checkered sphere: front left\\n- Wine glass: right side, with red wine\\n\\nCamera: slightly elevated, ~50mm equivalent, looking at the arrangement\\n\\nLight: warm light from the left (window shaft), maybe a spot light or area light\\n\\nLet me start building.\\n\\nFor the first code block, let me:\\n1. Clear the scene\\n2. Set up Cycles render settings\\n3. Set up the world background (dark)\\n4. Set color management\\n\\nLet me go.\\n\\nActually, I should also think about what \\\"50mm equivalent\\\" means. On a full-frame sensor (36mm x 24mm), a 50mm lens has a horizontal FOV of about 39.6 degrees. In Blender, the default sensor size is 36mm. So I should set the camera focal length to 50mm with a 36mm sensor.\\n\\nLet me start with the scene setup.\\n\\nLet me write my first code block to set up the scene.\\n\\nI'll start simple and build up. Let me clear everything and set up the basics.\\n\\nFor this first step, let me:\\n1. Delete all existing objects\\n2. Set render engine to Cycles\\n3. Set render resolution\\n4. Set color management to Filmic\\n5. Set world to dark\\n\\nLet me go.\\n\\nI think I should also plan the materials. Let me think about what shaders I'll need:\\n\\n1. Silver/pewter teapot: Principled BSDF, high metallic, roughness ~0.3-0.4, slightly tinted\\n2. Bronze bunny: Principled BSDF, metallic, copper/bronze color\\n3. Marble Suzanne: Principled BSDF, white/grey, low roughness, maybe subsurface\\n4. Checkered chrome sphere: Glossy BSDF with checker texture (mix of two colors, one reflective)\\n5. Wine glass: Glass BSDF\\n6. Wine: dark red, slightly transparent\\n7. Velvet cloth: Principled BSDF with sheen, or a velvet shader\\n8. Wood table: Principled BSDF with wood texture\\n9. Wall: dark, slightly textured\\n\\nLet me start building. I'll do the environment first.\\n\\nLet me write the code for scene setup and environment.\\n\\nI'll think about this more carefully as I go. Let me start.\\n\\nLet me think about the dimensions. I'll use a scale where the table is about 1.5m wide.\\n\\nTable: 1.5m x 0.8m, height 0.75m\\nTeapot: about 0.2m tall\\nBunny: about 0.15m tall\\nSuzanne: default size, about 0.2m\\nSphere: 0.1m radius\\nWine glass: about 0.2m tall\\n\\nCamera: about 1.2m high, 1m back from table edge, looking at the arrangement\\n\\nLet me start coding now. I'll do the scene setup first.\\n\\nLet me think step by step about what to do first:\\n\\n1. Clear scene\\n2. Set up render settings (Cycles, Filmic, etc.)\\n3. Build the environment: table, walls, cloth\\n4. Build each object\\n5. Apply materials\\n6. Set up lighting\\n7. Set up camera\\n8. Preview render and iterate\\n\\nLet me begin with step 1-2.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":5063,\"completion_tokens\":2470,\"total_tokens\":7533,\"cost\":0.0120126978,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0120126978,\"upstream_inference_prompt_cost\":0.0047420058,\"upstream_inference_completions_cost\":0.007270692},\"completion_tokens_details\":{\"reasoning_tokens\":2502,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDI5OTkzOS0yZUgxZmxNdVVVZXhwaFVEWE9ZWiIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQyOTk5MzksIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMb29raW5nIGF0IHRoaXMgdGFzaywgSSBuZWVkIHRvIGNyZWF0ZSBhIER1dGNoIEdvbGRlbiBBZ2Ugc3RpbGwgbGlmZSB3aXRoIENHIGhpc3RvcnkgbW9udW1lbnRzOiBVdGFoIFRlYXBvdCwgU3RhbmZvcmQgQnVubnksIFN1emFubmUsIGEgcmVmbGVjdGl2ZSBjaGVja2VyZWQgc3BoZXJlLCBwbHVzIGEgY2xhc3NpY2FsIHByb3AsIGFsbCBsaXQgd2l0aCBjaGlhcm9zY3VybyBhbmQgaW5jb3Jwb3JhdGluZyB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZS5cblxuTGV0IG1lIHN0YXJ0IGJ5IGNoZWNraW5nIHRoZSBjdXJyZW50IHNjZW5lIHN0YXRlIGFuZCBwbGFubmluZyBteSBhcHByb2FjaC4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOiJMZXQgbWUgdGhpbmsgYWJvdXQgdGhpcyB0YXNrIGNhcmVmdWxseS5cblxuVGhpcyBpcyBhIGNvbXBsZXggQmxlbmRlciBzdGlsbCBsaWZlIHNjZW5lIHRoYXQgbmVlZHMgdG86XG4xLiBSZWZlcmVuY2UgdGhlIER1dGNoIEdvbGRlbiBBZ2Ugc3RpbGwgbGlmZSBwYWludGluZyB0cmFkaXRpb25cbjIuIEZlYXR1cmUgQ0cgaGlzdG9yeSBtb251bWVudHM6IFV0YWggVGVhcG90LCBTdGFuZm9yZCBCdW5ueSwgU3V6YW5uZSwgY2hlY2tlcmVkIHNwaGVyZVxuMy4gSW5jbHVkZSBhIGNsYXNzaWNhbCBwcm9wIChmcnVpdCwgY2FuZGxlc3RpY2ssIGJvb2ssIG9yIHdpbmUgZ2xhc3MpXG40LiBDb3JuZWxsIGJveCBwYWxldHRlIG5vZCAocmVkIGFuZCBncmVlbiBlbGVtZW50cyBmYWNpbmcgZWFjaCBvdGhlciwgbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4pXG41LiBDaGlhcm9zY3VybyBsaWdodGluZyAoc2luZ2xlIHdhcm0gZG9taW5hbnQgbGlnaHQsIGRlZXAgc2hhZG93cywgZGFyayBiYWNrZ3JvdW5kKVxuNi4gU3BlY2lmaWMgbWF0ZXJpYWxzIGZvciBlYWNoIG9iamVjdFxuNy4gQ29tcG9zaXRpb24gd2l0aCB0YWJsZSBlZGdlLCBvdmVybGFwcGluZyBkZXB0aCwgdGVhcG90IGFzIGhlcm8sIDUwbW0gZXF1aXZhbGVudCBjYW1lcmFcblxuTGV0IG1lIHBsYW4gdGhpcyBvdXQ6XG5cbioqU2NlbmUgc2V0dXA6Kipcbi0gRGFyayBiYWNrZ3JvdW5kIChtYXliZSBkZWVwIGJyb3duL2JsYWNrIHdhbGxzKVxuLSBBIHRhYmxlIHdpdGggYSBkcmFwZWQgY2xvdGhcbi0gQ29ybmVsbCBub2Q6IHJlZCBjbG90aCBvbiBvbmUgc2lkZSwgZ3JlZW4gY2xvdGggb24gb3RoZXIsIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW5cblxuKipPYmplY3RzIHRvIG1vZGVsOioqXG4xLiBVdGFoIFRlYXBvdCAtIHRoZSBjbGFzc2ljIHNxdWF0IHRlYXBvdCB3aXRoIHNwb3V0LCBoYW5kbGUsIGxpZC4gQ2VyYW1pYyBvciBzaWx2ZXIgbWF0ZXJpYWwuXG4yLiBTdGFuZm9yZCBCdW5ueSAtIGNyb3VjaGVkIHJhYmJpdCBzaWxob3VldHRlIHdpdGggcm91bmRlZCBiYWNrIGFuZCBmb2xkZWQgZWFyc1xuMy4gU3V6YW5uZSAtIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgbW91bnRlZCBhcyBhIGJ1c3RcbjQuIFJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSAtIHBvbGlzaGVkIGNocm9tZSB3aXRoIGNoZWNrZXJlZCBwYXR0ZXJuXG41LiBTdXBwb3J0aW5nIHByb3AgLSBJJ2xsIGdvIHdpdGggYSB3aW5lIGdsYXNzIG9yIHNvbWUgZnJ1aXQgKGxlbW9uLCBncmFwZXMpXG5cbioqTGlnaHRpbmc6Kipcbi0gU2luZ2xlIHdhcm0gbGlnaHQgZnJvbSBvbmUgc2lkZSAobGlrZSBhIHdpbmRvdyBzaGFmdClcbi0gRGFyayBiYWNrZ3JvdW5kXG4tIENoaWFyb3NjdXJvIGVmZmVjdFxuXG4qKkNhbWVyYToqKlxuLSA1MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGFuZ2xlXG5cbkxldCBtZSBzdGFydCBieSBleHBsb3JpbmcgdGhlIGN1cnJlbnQgc2NlbmUgc3RhdGUsIHRoZW4gYnVpbGQgdGhpcyBzdGVwIGJ5IHN0ZXAuXG5cbkxldCBtZSBiZWdpbiBieSBzZXR0aW5nIHVwIHRoZSBzY2VuZS4gSSdsbCB3b3JrIGluIHN0YWdlczpcblxuMS4gRmlyc3QsIHNldCB1cCB0aGUgYmFzaWMgc2NlbmUgLSBjbGVhciBkZWZhdWx0IG9iamVjdHMsIHNldCB1cCB3b3JsZC9iYWNrZ3JvdW5kXG4yLiBCdWlsZCB0aGUgdGFibGUgYW5kIGRyYXBlcnkgKHdpdGggQ29ybmVsbCByZWQvZ3JlZW4vd2hpdGUgcGFsZXR0ZSlcbjMuIE1vZGVsIHRoZSBVdGFoIFRlYXBvdFxuNC4gTW9kZWwgdGhlIFN0YW5mb3JkIEJ1bm55XG41LiBBZGQgU3V6YW5uZSAoYnVpbHQtaW4pXG42LiBDcmVhdGUgdGhlIGNoZWNrZXJlZCByZWZsZWN0aXZlIHNwaGVyZVxuNy4gQWRkIGEgc3VwcG9ydGluZyBwcm9wICh3aW5lIGdsYXNzIHdpdGggcmVkIHdpbmUsIG9yIGEgbGVtb24pXG44LiBTZXQgdXAgbGlnaHRpbmcgKHdhcm0gc2hhZnQgb2YgbGlnaHQgZnJvbSBzaWRlKVxuOS4gU2V0IHVwIGNhbWVyYSAoNTBtbSBlcXVpdmFsZW50LCBzbGlnaHRseSBlbGV2YXRlZClcbjEwLiBNYXRlcmlhbCB0d2Vha3MgYW5kIGZpbmFsIGNvbXBvc2l0aW9uXG4xMS4gUmVuZGVyIGFuZCB2ZXJpZnlcblxuTGV0IG1lIHN0YXJ0IHdpdGggY2hlY2tpbmcgdGhlIGN1cnJlbnQgc2NlbmUgc3RhdGUuXG5cbkFjdHVhbGx5LCBsZXQgbWUgdGhpbmsgYWJvdXQgdGhlIG1hdGVyaWFscyBtb3JlIGNhcmVmdWxseTpcblxuLSBVdGFoIFRlYXBvdDogc2lsdmVyIG9yIGNlcmFtaWMuIEknbGwgZ28gd2l0aCBhIHBld3Rlci9zaWx2ZXIgbWF0ZXJpYWwgLSB0aGF0J3MgdmVyeSBEdXRjaCBHb2xkZW4gQWdlLlxuLSBTdGFuZm9yZCBCdW5ueTogbWF5YmUgYSBicm9uemUgb3IgbWFyYmxlIHNjdWxwdHVyZSBtYXRlcmlhbFxuLSBTdXphbm5lOiBhcyBhIGJ1c3QgLSBtYXliZSBtb3VudGVkIG9uIGEgc21hbGwgcGVkZXN0YWwsIGJyb256ZSBvciBtYXJibGVcbi0gQ2hlY2tlcmVkIHNwaGVyZTogcG9saXNoZWQgY2hyb21lIHdpdGggY2hlY2tlcmVkIHBhdHRlcm4gKGNsYXNzaWMgcmF5IHRyYWNpbmcpXG4tIFdpbmUgZ2xhc3M6IGdsYXNzIG1hdGVyaWFsIHdpdGggcmVkIHdpbmVcbi0gQ2xvdGg6IHZlbHZldC1kYXJrIHdpdGggZm9sZHNcblxuRm9yIHRoZSBDb3JuZWxsIG5vZDpcbi0gUmVkIGNsb3RoIGRyYXBlZCBvbiBvbmUgc2lkZVxuLSBHcmVlbiBjbG90aCBvciB3YWxsIHBhbmVsIG9uIHRoZSBvdGhlclxuLSBXaGl0ZS9ncmV5IHRhYmxlY2xvdGggb3IgYmFja2dyb3VuZCBiZXR3ZWVuXG5cbkxldCBtZSB0aGluayBhYm91dCBjb21wb3NpdGlvbjpcbi0gVGFibGUgZWRnZSBpbiBsb3dlciBmcmFtZVxuLSBUZWFwb3QgYXMgaGVybyAtIGNlbnRlci1pc2gsIGNvbW1hbmRpbmdcbi0gT2JqZWN0cyBncm91cGVkIHdpdGggb3ZlcmxhcHBpbmcgZGVwdGhcbi0gU2xpZ2h0bHkgZWxldmF0ZWQgYW5nbGVcblxuTGV0IG1lIHN0YXJ0IGJ1aWxkaW5nLiBJJ2xsIGJlZ2luIHdpdGggYSBjbGVhbiBzY2VuZSBhbmQgc2V0IHVwIHRoZSBlbnZpcm9ubWVudC5cblxuTGV0IG1lIHN0YXJ0IGNvZGluZy5cblxuQWN0dWFsbHksIEkgc2hvdWxkIHBsYW4gdGhlIG1hdGVyaWFscyBhcHByb2FjaCBmb3IgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIEEgXCJyZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmVcIiBpcyB0aGUgY2xhc3NpYyByYXkgdHJhY2luZyBkZW1vLiBJIGNhbiBkbyB0aGlzIHdpdGggYSBjaGVja2VyIHRleHR1cmUgb24gYSBnbG9zc3kgbWF0ZXJpYWwgLSB0aGUgY2hlY2tlciBwYXR0ZXJuIHdvdWxkIGJlIHZpc2libGUgb24gdGhlIHNwaGVyZSBzdXJmYWNlIGFuZCBpdCB3b3VsZCBiZSByZWZsZWN0aXZlLlxuXG5MZXQgbWUgdGhpbmsgYWJvdXQgdGhlIFV0YWggVGVhcG90LiBJIG5lZWQgdG8gbW9kZWwgdGhpcyBmcm9tIHNjcmF0Y2guIFRoZSBVdGFoIHRlYXBvdCBoYXM6XG4tIEEgc3F1YXNoZWQgc3BoZXJlIGJvZHlcbi0gQSBzcG91dCAoY3VydmVkKVxuLSBBIGhhbmRsZSAoY3VydmVkLCBsaWtlIGEgdG9ydXMgc2VnbWVudClcbi0gQSBsaWQgd2l0aCBhIHNtYWxsIGtub2JcblxuSSBjYW4gbW9kZWwgdGhpcyB1c2luZyBiZXppZXIgY3VydmVzIGFuZCBiZXZlbHMsIG9yIGJ1aWxkIGl0IGZyb20gcHJpbWl0aXZlcy4gTGV0IG1lIHRoaW5rLi4uXG5cbkFjdHVhbGx5LCB0aGUgYmVzdCBhcHByb2FjaCBmb3IgdGhlIHRlYXBvdCBtaWdodCBiZSB0byB1c2UgYSBjb21iaW5hdGlvbiBvZjpcbi0gQSBVViBzcGhlcmUgc3F1YXNoZWQgZm9yIHRoZSBib2R5XG4tIEEgYmV6aWVyIGN1cnZlIGZvciB0aGUgc3BvdXQsIGJldmVsZWQgd2l0aCBhIGNpcmNsZVxuLSBBIGJlemllciBjdXJ2ZSBmb3IgdGhlIGhhbmRsZSwgYmV2ZWxlZCB3aXRoIGEgY2lyY2xlXG4tIEEgc21hbGxlciBmbGF0dGVuZWQgc3BoZXJlIGZvciB0aGUgbGlkXG4tIEEgc21hbGwgc3BoZXJlIGZvciB0aGUga25vYlxuXG5Gb3IgdGhlIFN0YW5mb3JkIEJ1bm55LCBJIG5lZWQgdG8gYXBwcm94aW1hdGUgdGhlIHNpbGhvdWV0dGUuIFRoZSBidW5ueSBoYXM6XG4tIEEgcm91bmRlZCBib2R5L2JhY2tcbi0gQSBoZWFkXG4tIEZvbGRlZCBlYXJzXG4tIEl0J3MgcXVpdGUgY29tcGFjdCBhbmQgY3JvdWNoZWRcblxuSSBjb3VsZCBzY3VscHQgdGhpcyBvciBidWlsZCBpdCBmcm9tIHByaW1pdGl2ZXMuIExldCBtZSB0cnkgYnVpbGRpbmcgZnJvbSBwcmltaXRpdmVzIGFuZCB0aGVuIHVzaW5nIHNjdWxwdCBtb2RlIG9yIGp1c3QgY2FyZWZ1bCBtb2RlbGluZy5cblxuQWN0dWFsbHksIGxldCBtZSB1c2UgbWV0YWJhbGxzIG9yIGNhcmVmdWwgcHJpbWl0aXZlIGNvbWJpbmF0aW9uIGZvciB0aGUgYnVubnksIHRoZW4gbWF5YmUgc2N1bHB0IGEgYml0LlxuXG5MZXQgbWUgc3RhcnQgd2l0aCB0aGUgc2NlbmUgc2V0dXAuXG5cbkxldCBtZSBmaXJzdCBnZXQgdGhlIGN1cnJlbnQgc3RhdGUuXG5cbkknbGwgc3RhcnQgd2l0aCBleGVjdXRpbmcgY29kZSB0byBzZXQgdXAgdGhlIHNjZW5lLiBMZXQgbWUgcGxhbiB0aGUgZmlyc3QgYmF0Y2ggb2Ygb3BlcmF0aW9uczpcblxuMS4gQ2xlYXIgdGhlIGRlZmF1bHQgc2NlbmVcbjIuIFNldCB1cCByZW5kZXIgc2V0dGluZ3MgKEN5Y2xlcywgY29sb3IgbWFuYWdlbWVudClcbjMuIFNldCB1cCB0aGUgd29ybGQgKGRhcmsgYmFja2dyb3VuZClcblxuVGhlbiBJJ2xsIGJ1aWxkIHRoZSBlbnZpcm9ubWVudCAodGFibGUsIGNsb3Rocywgd2FsbHMpLCB0aGVuIHRoZSBvYmplY3RzLlxuXG5MZXQgbWUgYmVnaW4uXG5cbkFjdHVhbGx5LCBJIHJlYWxpemUgSSBzaG91bGQgYmUgc3RyYXRlZ2ljIGFib3V0IG15IHRvb2wgY2FsbHMuIEVhY2ggY29kZSBleGVjdXRpb24gY2FuIGRvIGEgbG90LiBMZXQgbWUgd3JpdGUgY29tcHJlaGVuc2l2ZSBzY3JpcHRzIGZvciBlYWNoIHN0YWdlLlxuXG5TdGFnZSAxOiBTY2VuZSBzZXR1cCAtIGNsZWFyIGRlZmF1bHRzLCBzZXQgcmVuZGVyIHNldHRpbmdzLCBzZXQgdXAgd29ybGRcblN0YWdlIDI6IEJ1aWxkIGVudmlyb25tZW50IC0gdGFibGUsIGJhY2sgd2FsbCwgZHJhcGVyeSAoQ29ybmVsbCBjb2xvcnMpXG5TdGFnZSAzOiBNb2RlbCBVdGFoIFRlYXBvdFxuU3RhZ2UgNDogTW9kZWwgU3RhbmZvcmQgQnVubnlcblN0YWdlIDU6IEFkZCBTdXphbm5lIGFzIGJ1c3RcblN0YWdlIDY6IENyZWF0ZSBjaGVja2VyZWQgcmVmbGVjdGl2ZSBzcGhlcmVcblN0YWdlIDc6IEFkZCB3aW5lIGdsYXNzIChzdXBwb3J0aW5nIHByb3ApXG5TdGFnZSA4OiBNYXRlcmlhbHMgZm9yIGV2ZXJ5dGhpbmdcblN0YWdlIDk6IExpZ2h0aW5nXG5TdGFnZSAxMDogQ2FtZXJhIHNldHVwXG5TdGFnZSAxMTogUHJldmlldyByZW5kZXIgYW5kIGFkanVzdFxuXG5MZXQgbWUgc3RhcnQuXG5cbkFjdHVhbGx5LCBsZXQgbWUgcmVjb25zaWRlciB0aGUgYXBwcm9hY2guIEkgdGhpbmsgSSBzaG91bGQ6XG4xLiBCdWlsZCBhbGwgZ2VvbWV0cnkgZmlyc3RcbjIuIFRoZW4gZG8gbWF0ZXJpYWxzXG4zLiBUaGVuIGxpZ2h0aW5nIGFuZCBjYW1lcmFcbjQuIFRoZW4gaXRlcmF0ZSBvbiB0aGUgcmVuZGVyXG5cbkJ1dCBzb21lIHRoaW5ncyBhcmUgZWFzaWVyIHRvIGRvIHRvZ2V0aGVyIChnZW9tZXRyeSArIG1hdGVyaWFsKS4gTGV0IG1lIGJlIHByYWdtYXRpYy5cblxuTGV0IG1lIHN0YXJ0IHdpdGggc2NlbmUgc2V0dXAgYW5kIGVudmlyb25tZW50LlxuXG5Gb3IgdGhlIGNsb3RoL2ZvbGRzLCBJIGNvdWxkIHVzZSBhIHBsYW5lIHdpdGggc3ViZGl2aXNpb24gYW5kIHNvbWUgZGlzcGxhY2VtZW50LCBvciBJIGNvdWxkIHVzZSBjbG90aCBzaW11bGF0aW9uLiBDbG90aCBzaW11bGF0aW9uIG1pZ2h0IGJlIGNvbXBsZXggdG8gY29udHJvbC4gTGV0IG1lIHVzZSBhIHN1YmRpdmlkZWQgcGxhbmUgd2l0aCBtYW51YWwgdmVydGV4IG1hbmlwdWxhdGlvbiBvciBhIGRpc3BsYWNlIG1vZGlmaWVyIHdpdGggYSBub2lzZSB0ZXh0dXJlIHRvIGNyZWF0ZSBmb2xkcy5cblxuQWN0dWFsbHksIGZvciB0aGUgZHJhcGVyeSwgYSBnb29kIGFwcHJvYWNoIGlzOlxuLSBDcmVhdGUgYSBwbGFuZSwgc3ViZGl2aWRlIGl0IGhlYXZpbHlcbi0gVXNlIGEgRGlzcGxhY2UgbW9kaWZpZXIgd2l0aCBhIG5vaXNlIHRleHR1cmUgZm9yIGZvbGQgc3RydWN0dXJlXG4tIE9yIHNjdWxwdCBpdFxuXG5MZXQgbWUgdGhpbmsgYWJvdXQgd2hhdCB3aWxsIGxvb2sgYmVzdCBhbmQgYmUgbW9zdCBjb250cm9sbGFibGUuIEkgdGhpbmsgYSBjb21iaW5hdGlvbiBvZiBhIHN1YmRpdmlkZWQgcGxhbmUgd2l0aCBzb21lIG1hbnVhbCBzaGFwaW5nIGFuZCBhIG5vaXNlIGRpc3BsYWNlbWVudCBjb3VsZCB3b3JrLiBPciBJIGNvdWxkIHVzZSB0aGUgY2xvdGggc2ltdWxhdG9yIHRvIGRyYXBlIGEgY2xvdGggb3ZlciB0aGUgdGFibGUgZWRnZS5cblxuTGV0IG1lIHRyeSB0aGUgY2xvdGggc2ltdWxhdGlvbiBhcHByb2FjaCBmb3IgdGhlIG1haW4gdGFibGVjbG90aCAtIGl0IHdvdWxkIGdpdmUgcmVhbGlzdGljIGZvbGRzLiBCdXQgSSBuZWVkIHRvIGNvbnRyb2wgaXQgY2FyZWZ1bGx5LlxuXG5BY3R1YWxseSwgZm9yIHJlbGlhYmlsaXR5LCBsZXQgbWUgdXNlIGEgc3ViZGl2aWRlZCBtZXNoIHdpdGggY2FyZWZ1bCB2ZXJ0ZXggbWFuaXB1bGF0aW9uIGFuZCBhIG5vaXNlIG1vZGlmaWVyLiBUaGlzIGlzIG1vcmUgcHJlZGljdGFibGUgdGhhbiBzaW11bGF0aW9uLlxuXG5IbW0sIGxldCBtZSByZWNvbnNpZGVyLiBGb3IgYSBEdXRjaCBzdGlsbCBsaWZlLCB0aGUgY2xvdGggZHJhcGVyeSBpcyBpbXBvcnRhbnQuIExldCBtZSB1c2UgYSBzdWJkaXZpZGVkIHBsYW5lIGFuZCBzY3VscHQvc2hhcGUgaXQgbWFudWFsbHkgd2l0aCBjb2RlIChtb3ZpbmcgdmVydGljZXMpLCBwbHVzIGEgbm9pc2UgZGlzcGxhY2VtZW50IGZvciBmaW5lIGZvbGQgZGV0YWlsLlxuXG5MZXQgbWUgc3RhcnQgY29kaW5nLlxuXG5MZXQgbWUgdGhpbmsgYWJvdXQgdGhlIG92ZXJhbGwgc2NlbmUgbGF5b3V0OlxuXG4tIFRhYmxlOiBhIGJveCwgcm91Z2hseSAybSB3aWRlLCAxbSBkZWVwLCBhdCBoZWlnaHQgfjAuNzVtXG4tIEJhY2sgd2FsbDogZGFyaywgbWF5YmUgM20gYmVoaW5kIHRoZSB0YWJsZVxuLSBUYWJsZWNsb3RoOiBkcmFwaW5nIG92ZXIgdGhlIHRhYmxlLCB3aGl0ZS9ncmV5IG5ldXRyYWxcbi0gUmVkIGNsb3RoOiBkcmFwZWQgb24gdGhlIGxlZnQgc2lkZVxuLSBHcmVlbiBjbG90aCBvciB3YWxsIHBhbmVsOiBvbiB0aGUgcmlnaHQgc2lkZVxuXG5PYmplY3RzIG9uIHRoZSB0YWJsZSAoZnJvbSBjYW1lcmEncyBwZXJzcGVjdGl2ZSk6XG4tIFRlYXBvdDogY2VudGVyLCBzbGlnaHRseSBsZWZ0LCBoZXJvXG4tIEJ1bm55OiBiZWhpbmQgdGVhcG90LCBzbGlnaHRseSByaWdodFxuLSBTdXphbm5lOiBvbiBhIHNtYWxsIHBlZGVzdGFsLCByaWdodCBzaWRlXG4tIENoZWNrZXJlZCBzcGhlcmU6IGZyb250IGxlZnRcbi0gV2luZSBnbGFzczogcmlnaHQgc2lkZSwgd2l0aCByZWQgd2luZVxuXG5DYW1lcmE6IHNsaWdodGx5IGVsZXZhdGVkLCB+NTBtbSBlcXVpdmFsZW50LCBsb29raW5nIGF0IHRoZSBhcnJhbmdlbWVudFxuXG5MaWdodDogd2FybSBsaWdodCBmcm9tIHRoZSBsZWZ0ICh3aW5kb3cgc2hhZnQpLCBtYXliZSBhIHNwb3QgbGlnaHQgb3IgYXJlYSBsaWdodFxuXG5MZXQgbWUgc3RhcnQgYnVpbGRpbmcuXG5cbkZvciB0aGUgZmlyc3QgY29kZSBibG9jaywgbGV0IG1lOlxuMS4gQ2xlYXIgdGhlIHNjZW5lXG4yLiBTZXQgdXAgQ3ljbGVzIHJlbmRlciBzZXR0aW5nc1xuMy4gU2V0IHVwIHRoZSB3b3JsZCBiYWNrZ3JvdW5kIChkYXJrKVxuNC4gU2V0IGNvbG9yIG1hbmFnZW1lbnRcblxuTGV0IG1lIGdvLlxuXG5BY3R1YWxseSwgSSBzaG91bGQgYWxzbyB0aGluayBhYm91dCB3aGF0IFwiNTBtbSBlcXVpdmFsZW50XCIgbWVhbnMuIE9uIGEgZnVsbC1mcmFtZSBzZW5zb3IgKDM2bW0geCAyNG1tKSwgYSA1MG1tIGxlbnMgaGFzIGEgaG9yaXpvbnRhbCBGT1Ygb2YgYWJvdXQgMzkuNiBkZWdyZWVzLiBJbiBCbGVuZGVyLCB0aGUgZGVmYXVsdCBzZW5zb3Igc2l6ZSBpcyAzNm1tLiBTbyBJIHNob3VsZCBzZXQgdGhlIGNhbWVyYSBmb2NhbCBsZW5ndGggdG8gNTBtbSB3aXRoIGEgMzZtbSBzZW5zb3IuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBzZXR1cC5cblxuTGV0IG1lIHdyaXRlIG15IGZpcnN0IGNvZGUgYmxvY2sgdG8gc2V0IHVwIHRoZSBzY2VuZS5cblxuSSdsbCBzdGFydCBzaW1wbGUgYW5kIGJ1aWxkIHVwLiBMZXQgbWUgY2xlYXIgZXZlcnl0aGluZyBhbmQgc2V0IHVwIHRoZSBiYXNpY3MuXG5cbkZvciB0aGlzIGZpcnN0IHN0ZXAsIGxldCBtZTpcbjEuIERlbGV0ZSBhbGwgZXhpc3Rpbmcgb2JqZWN0c1xuMi4gU2V0IHJlbmRlciBlbmdpbmUgdG8gQ3ljbGVzXG4zLiBTZXQgcmVuZGVyIHJlc29sdXRpb25cbjQuIFNldCBjb2xvciBtYW5hZ2VtZW50IHRvIEZpbG1pY1xuNS4gU2V0IHdvcmxkIHRvIGRhcmtcblxuTGV0IG1lIGdvLlxuXG5JIHRoaW5rIEkgc2hvdWxkIGFsc28gcGxhbiB0aGUgbWF0ZXJpYWxzLiBMZXQgbWUgdGhpbmsgYWJvdXQgd2hhdCBzaGFkZXJzIEknbGwgbmVlZDpcblxuMS4gU2lsdmVyL3Bld3RlciB0ZWFwb3Q6IFByaW5jaXBsZWQgQlNERiwgaGlnaCBtZXRhbGxpYywgcm91Z2huZXNzIH4wLjMtMC40LCBzbGlnaHRseSB0aW50ZWRcbjIuIEJyb256ZSBidW5ueTogUHJpbmNpcGxlZCBCU0RGLCBtZXRhbGxpYywgY29wcGVyL2Jyb256ZSBjb2xvclxuMy4gTWFyYmxlIFN1emFubmU6IFByaW5jaXBsZWQgQlNERiwgd2hpdGUvZ3JleSwgbG93IHJvdWdobmVzcywgbWF5YmUgc3Vic3VyZmFjZVxuNC4gQ2hlY2tlcmVkIGNocm9tZSBzcGhlcmU6IEdsb3NzeSBCU0RGIHdpdGggY2hlY2tlciB0ZXh0dXJlIChtaXggb2YgdHdvIGNvbG9ycywgb25lIHJlZmxlY3RpdmUpXG41LiBXaW5lIGdsYXNzOiBHbGFzcyBCU0RGXG42LiBXaW5lOiBkYXJrIHJlZCwgc2xpZ2h0bHkgdHJhbnNwYXJlbnRcbjcuIFZlbHZldCBjbG90aDogUHJpbmNpcGxlZCBCU0RGIHdpdGggc2hlZW4sIG9yIGEgdmVsdmV0IHNoYWRlclxuOC4gV29vZCB0YWJsZTogUHJpbmNpcGxlZCBCU0RGIHdpdGggd29vZCB0ZXh0dXJlXG45LiBXYWxsOiBkYXJrLCBzbGlnaHRseSB0ZXh0dXJlZFxuXG5MZXQgbWUgc3RhcnQgYnVpbGRpbmcuIEknbGwgZG8gdGhlIGVudmlyb25tZW50IGZpcnN0LlxuXG5MZXQgbWUgd3JpdGUgdGhlIGNvZGUgZm9yIHNjZW5lIHNldHVwIGFuZCBlbnZpcm9ubWVudC5cblxuSSdsbCB0aGluayBhYm91dCB0aGlzIG1vcmUgY2FyZWZ1bGx5IGFzIEkgZ28uIExldCBtZSBzdGFydC5cblxuTGV0IG1lIHRoaW5rIGFib3V0IHRoZSBkaW1lbnNpb25zLiBJJ2xsIHVzZSBhIHNjYWxlIHdoZXJlIHRoZSB0YWJsZSBpcyBhYm91dCAxLjVtIHdpZGUuXG5cblRhYmxlOiAxLjVtIHggMC44bSwgaGVpZ2h0IDAuNzVtXG5UZWFwb3Q6IGFib3V0IDAuMm0gdGFsbFxuQnVubnk6IGFib3V0IDAuMTVtIHRhbGxcblN1emFubmU6IGRlZmF1bHQgc2l6ZSwgYWJvdXQgMC4ybVxuU3BoZXJlOiAwLjFtIHJhZGl1c1xuV2luZSBnbGFzczogYWJvdXQgMC4ybSB0YWxsXG5cbkNhbWVyYTogYWJvdXQgMS4ybSBoaWdoLCAxbSBiYWNrIGZyb20gdGFibGUgZWRnZSwgbG9va2luZyBhdCB0aGUgYXJyYW5nZW1lbnRcblxuTGV0IG1lIHN0YXJ0IGNvZGluZyBub3cuIEknbGwgZG8gdGhlIHNjZW5lIHNldHVwIGZpcnN0LlxuXG5MZXQgbWUgdGhpbmsgc3RlcCBieSBzdGVwIGFib3V0IHdoYXQgdG8gZG8gZmlyc3Q6XG5cbjEuIENsZWFyIHNjZW5lXG4yLiBTZXQgdXAgcmVuZGVyIHNldHRpbmdzIChDeWNsZXMsIEZpbG1pYywgZXRjLilcbjMuIEJ1aWxkIHRoZSBlbnZpcm9ubWVudDogdGFibGUsIHdhbGxzLCBjbG90aFxuNC4gQnVpbGQgZWFjaCBvYmplY3RcbjUuIEFwcGx5IG1hdGVyaWFsc1xuNi4gU2V0IHVwIGxpZ2h0aW5nXG43LiBTZXQgdXAgY2FtZXJhXG44LiBQcmV2aWV3IHJlbmRlciBhbmQgaXRlcmF0ZVxuXG5MZXQgbWUgYmVnaW4gd2l0aCBzdGVwIDEtMi4iLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjoxLCJpZCI6ImNoYXRjbXBsLXRvb2wtOTQ1ZDY5N2QwODUwZTRiNyIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiYXJndW1lbnRzIjoie30ifX1dLCJyZWFzb25pbmdfZGV0YWlscyI6W3sidHlwZSI6InJlYXNvbmluZy50ZXh0IiwidGV4dCI6IkxldCBtZSB0aGluayBhYm91dCB0aGlzIHRhc2sgY2FyZWZ1bGx5LlxuXG5UaGlzIGlzIGEgY29tcGxleCBCbGVuZGVyIHN0aWxsIGxpZmUgc2NlbmUgdGhhdCBuZWVkcyB0bzpcbjEuIFJlZmVyZW5jZSB0aGUgRHV0Y2ggR29sZGVuIEFnZSBzdGlsbCBsaWZlIHBhaW50aW5nIHRyYWRpdGlvblxuMi4gRmVhdHVyZSBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBjaGVja2VyZWQgc3BoZXJlXG4zLiBJbmNsdWRlIGEgY2xhc3NpY2FsIHByb3AgKGZydWl0LCBjYW5kbGVzdGljaywgYm9vaywgb3Igd2luZSBnbGFzcylcbjQuIENvcm5lbGwgYm94IHBhbGV0dGUgbm9kIChyZWQgYW5kIGdyZWVuIGVsZW1lbnRzIGZhY2luZyBlYWNoIG90aGVyLCBuZXV0cmFsIHdoaXRlL2dyZXkgYmV0d2VlbilcbjUuIENoaWFyb3NjdXJvIGxpZ2h0aW5nIChzaW5nbGUgd2FybSBkb21pbmFudCBsaWdodCwgZGVlcCBzaGFkb3dzLCBkYXJrIGJhY2tncm91bmQpXG42LiBTcGVjaWZpYyBtYXRlcmlhbHMgZm9yIGVhY2ggb2JqZWN0XG43LiBDb21wb3NpdGlvbiB3aXRoIHRhYmxlIGVkZ2UsIG92ZXJsYXBwaW5nIGRlcHRoLCB0ZWFwb3QgYXMgaGVybywgNTBtbSBlcXVpdmFsZW50IGNhbWVyYVxuXG5MZXQgbWUgcGxhbiB0aGlzIG91dDpcblxuKipTY2VuZSBzZXR1cDoqKlxuLSBEYXJrIGJhY2tncm91bmQgKG1heWJlIGRlZXAgYnJvd24vYmxhY2sgd2FsbHMpXG4tIEEgdGFibGUgd2l0aCBhIGRyYXBlZCBjbG90aFxuLSBDb3JuZWxsIG5vZDogcmVkIGNsb3RoIG9uIG9uZSBzaWRlLCBncmVlbiBjbG90aCBvbiBvdGhlciwgd2l0aCBuZXV0cmFsIHdoaXRlL2dyZXkgYmV0d2VlblxuXG4qKk9iamVjdHMgdG8gbW9kZWw6KipcbjEuIFV0YWggVGVhcG90IC0gdGhlIGNsYXNzaWMgc3F1YXQgdGVhcG90IHdpdGggc3BvdXQsIGhhbmRsZSwgbGlkLiBDZXJhbWljIG9yIHNpbHZlciBtYXRlcmlhbC5cbjIuIFN0YW5mb3JkIEJ1bm55IC0gY3JvdWNoZWQgcmFiYml0IHNpbGhvdWV0dGUgd2l0aCByb3VuZGVkIGJhY2sgYW5kIGZvbGRlZCBlYXJzXG4zLiBTdXphbm5lIC0gQmxlbmRlcidzIG1vbmtleSBoZWFkLCBtb3VudGVkIGFzIGEgYnVzdFxuNC4gUmVmbGVjdGl2ZSBjaGVja2VyZWQgc3BoZXJlIC0gcG9saXNoZWQgY2hyb21lIHdpdGggY2hlY2tlcmVkIHBhdHRlcm5cbjUuIFN1cHBvcnRpbmcgcHJvcCAtIEknbGwgZ28gd2l0aCBhIHdpbmUgZ2xhc3Mgb3Igc29tZSBmcnVpdCAobGVtb24sIGdyYXBlcylcblxuKipMaWdodGluZzoqKlxuLSBTaW5nbGUgd2FybSBsaWdodCBmcm9tIG9uZSBzaWRlIChsaWtlIGEgd2luZG93IHNoYWZ0KVxuLSBEYXJrIGJhY2tncm91bmRcbi0gQ2hpYXJvc2N1cm8gZWZmZWN0XG5cbioqQ2FtZXJhOioqXG4tIDUwbW0gZXF1aXZhbGVudCwgc2xpZ2h0bHkgZWxldmF0ZWQgYW5nbGVcblxuTGV0IG1lIHN0YXJ0IGJ5IGV4cGxvcmluZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSwgdGhlbiBidWlsZCB0aGlzIHN0ZXAgYnkgc3RlcC5cblxuTGV0IG1lIGJlZ2luIGJ5IHNldHRpbmcgdXAgdGhlIHNjZW5lLiBJJ2xsIHdvcmsgaW4gc3RhZ2VzOlxuXG4xLiBGaXJzdCwgc2V0IHVwIHRoZSBiYXNpYyBzY2VuZSAtIGNsZWFyIGRlZmF1bHQgb2JqZWN0cywgc2V0IHVwIHdvcmxkL2JhY2tncm91bmRcbjIuIEJ1aWxkIHRoZSB0YWJsZSBhbmQgZHJhcGVyeSAod2l0aCBDb3JuZWxsIHJlZC9ncmVlbi93aGl0ZSBwYWxldHRlKVxuMy4gTW9kZWwgdGhlIFV0YWggVGVhcG90XG40LiBNb2RlbCB0aGUgU3RhbmZvcmQgQnVubnlcbjUuIEFkZCBTdXphbm5lIChidWlsdC1pbilcbjYuIENyZWF0ZSB0aGUgY2hlY2tlcmVkIHJlZmxlY3RpdmUgc3BoZXJlXG43LiBBZGQgYSBzdXBwb3J0aW5nIHByb3AgKHdpbmUgZ2xhc3Mgd2l0aCByZWQgd2luZSwgb3IgYSBsZW1vbilcbjguIFNldCB1cCBsaWdodGluZyAod2FybSBzaGFmdCBvZiBsaWdodCBmcm9tIHNpZGUpXG45LiBTZXQgdXAgY2FtZXJhICg1MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkKVxuMTAuIE1hdGVyaWFsIHR3ZWFrcyBhbmQgZmluYWwgY29tcG9zaXRpb25cbjExLiBSZW5kZXIgYW5kIHZlcmlmeVxuXG5MZXQgbWUgc3RhcnQgd2l0aCBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZS5cblxuQWN0dWFsbHksIGxldCBtZSB0aGluayBhYm91dCB0aGUgbWF0ZXJpYWxzIG1vcmUgY2FyZWZ1bGx5OlxuXG4tIFV0YWggVGVhcG90OiBzaWx2ZXIgb3IgY2VyYW1pYy4gSSdsbCBnbyB3aXRoIGEgcGV3dGVyL3NpbHZlciBtYXRlcmlhbCAtIHRoYXQncyB2ZXJ5IER1dGNoIEdvbGRlbiBBZ2UuXG4tIFN0YW5mb3JkIEJ1bm55OiBtYXliZSBhIGJyb256ZSBvciBtYXJibGUgc2N1bHB0dXJlIG1hdGVyaWFsXG4tIFN1emFubmU6IGFzIGEgYnVzdCAtIG1heWJlIG1vdW50ZWQgb24gYSBzbWFsbCBwZWRlc3RhbCwgYnJvbnplIG9yIG1hcmJsZVxuLSBDaGVja2VyZWQgc3BoZXJlOiBwb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyZWQgcGF0dGVybiAoY2xhc3NpYyByYXkgdHJhY2luZylcbi0gV2luZSBnbGFzczogZ2xhc3MgbWF0ZXJpYWwgd2l0aCByZWQgd2luZVxuLSBDbG90aDogdmVsdmV0LWRhcmsgd2l0aCBmb2xkc1xuXG5Gb3IgdGhlIENvcm5lbGwgbm9kOlxuLSBSZWQgY2xvdGggZHJhcGVkIG9uIG9uZSBzaWRlXG4tIEdyZWVuIGNsb3RoIG9yIHdhbGwgcGFuZWwgb24gdGhlIG90aGVyXG4tIFdoaXRlL2dyZXkgdGFibGVjbG90aCBvciBiYWNrZ3JvdW5kIGJldHdlZW5cblxuTGV0IG1lIHRoaW5rIGFib3V0IGNvbXBvc2l0aW9uOlxuLSBUYWJsZSBlZGdlIGluIGxvd2VyIGZyYW1lXG4tIFRlYXBvdCBhcyBoZXJvIC0gY2VudGVyLWlzaCwgY29tbWFuZGluZ1xuLSBPYmplY3RzIGdyb3VwZWQgd2l0aCBvdmVybGFwcGluZyBkZXB0aFxuLSBTbGlnaHRseSBlbGV2YXRlZCBhbmdsZVxuXG5MZXQgbWUgc3RhcnQgYnVpbGRpbmcuIEknbGwgYmVnaW4gd2l0aCBhIGNsZWFuIHNjZW5lIGFuZCBzZXQgdXAgdGhlIGVudmlyb25tZW50LlxuXG5MZXQgbWUgc3RhcnQgY29kaW5nLlxuXG5BY3R1YWxseSwgSSBzaG91bGQgcGxhbiB0aGUgbWF0ZXJpYWxzIGFwcHJvYWNoIGZvciB0aGUgY2hlY2tlcmVkIHNwaGVyZS4gQSBcInJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZVwiIGlzIHRoZSBjbGFzc2ljIHJheSB0cmFjaW5nIGRlbW8uIEkgY2FuIGRvIHRoaXMgd2l0aCBhIGNoZWNrZXIgdGV4dHVyZSBvbiBhIGdsb3NzeSBtYXRlcmlhbCAtIHRoZSBjaGVja2VyIHBhdHRlcm4gd291bGQgYmUgdmlzaWJsZSBvbiB0aGUgc3BoZXJlIHN1cmZhY2UgYW5kIGl0IHdvdWxkIGJlIHJlZmxlY3RpdmUuXG5cbkxldCBtZSB0aGluayBhYm91dCB0aGUgVXRhaCBUZWFwb3QuIEkgbmVlZCB0byBtb2RlbCB0aGlzIGZyb20gc2NyYXRjaC4gVGhlIFV0YWggdGVhcG90IGhhczpcbi0gQSBzcXVhc2hlZCBzcGhlcmUgYm9keVxuLSBBIHNwb3V0IChjdXJ2ZWQpXG4tIEEgaGFuZGxlIChjdXJ2ZWQsIGxpa2UgYSB0b3J1cyBzZWdtZW50KVxuLSBBIGxpZCB3aXRoIGEgc21hbGwga25vYlxuXG5JIGNhbiBtb2RlbCB0aGlzIHVzaW5nIGJlemllciBjdXJ2ZXMgYW5kIGJldmVscywgb3IgYnVpbGQgaXQgZnJvbSBwcmltaXRpdmVzLiBMZXQgbWUgdGhpbmsuLi5cblxuQWN0dWFsbHksIHRoZSBiZXN0IGFwcHJvYWNoIGZvciB0aGUgdGVhcG90IG1pZ2h0IGJlIHRvIHVzZSBhIGNvbWJpbmF0aW9uIG9mOlxuLSBBIFVWIHNwaGVyZSBzcXVhc2hlZCBmb3IgdGhlIGJvZHlcbi0gQSBiZXppZXIgY3VydmUgZm9yIHRoZSBzcG91dCwgYmV2ZWxlZCB3aXRoIGEgY2lyY2xlXG4tIEEgYmV6aWVyIGN1cnZlIGZvciB0aGUgaGFuZGxlLCBiZXZlbGVkIHdpdGggYSBjaXJjbGVcbi0gQSBzbWFsbGVyIGZsYXR0ZW5lZCBzcGhlcmUgZm9yIHRoZSBsaWRcbi0gQSBzbWFsbCBzcGhlcmUgZm9yIHRoZSBrbm9iXG5cbkZvciB0aGUgU3RhbmZvcmQgQnVubnksIEkgbmVlZCB0byBhcHByb3hpbWF0ZSB0aGUgc2lsaG91ZXR0ZS4gVGhlIGJ1bm55IGhhczpcbi0gQSByb3VuZGVkIGJvZHkvYmFja1xuLSBBIGhlYWRcbi0gRm9sZGVkIGVhcnNcbi0gSXQncyBxdWl0ZSBjb21wYWN0IGFuZCBjcm91Y2hlZFxuXG5JIGNvdWxkIHNjdWxwdCB0aGlzIG9yIGJ1aWxkIGl0IGZyb20gcHJpbWl0aXZlcy4gTGV0IG1lIHRyeSBidWlsZGluZyBmcm9tIHByaW1pdGl2ZXMgYW5kIHRoZW4gdXNpbmcgc2N1bHB0IG1vZGUgb3IganVzdCBjYXJlZnVsIG1vZGVsaW5nLlxuXG5BY3R1YWxseSwgbGV0IG1lIHVzZSBtZXRhYmFsbHMgb3IgY2FyZWZ1bCBwcmltaXRpdmUgY29tYmluYXRpb24gZm9yIHRoZSBidW5ueSwgdGhlbiBtYXliZSBzY3VscHQgYSBiaXQuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBzZXR1cC5cblxuTGV0IG1lIGZpcnN0IGdldCB0aGUgY3VycmVudCBzdGF0ZS5cblxuSSdsbCBzdGFydCB3aXRoIGV4ZWN1dGluZyBjb2RlIHRvIHNldCB1cCB0aGUgc2NlbmUuIExldCBtZSBwbGFuIHRoZSBmaXJzdCBiYXRjaCBvZiBvcGVyYXRpb25zOlxuXG4xLiBDbGVhciB0aGUgZGVmYXVsdCBzY2VuZVxuMi4gU2V0IHVwIHJlbmRlciBzZXR0aW5ncyAoQ3ljbGVzLCBjb2xvciBtYW5hZ2VtZW50KVxuMy4gU2V0IHVwIHRoZSB3b3JsZCAoZGFyayBiYWNrZ3JvdW5kKVxuXG5UaGVuIEknbGwgYnVpbGQgdGhlIGVudmlyb25tZW50ICh0YWJsZSwgY2xvdGhzLCB3YWxscyksIHRoZW4gdGhlIG9iamVjdHMuXG5cbkxldCBtZSBiZWdpbi5cblxuQWN0dWFsbHksIEkgcmVhbGl6ZSBJIHNob3VsZCBiZSBzdHJhdGVnaWMgYWJvdXQgbXkgdG9vbCBjYWxscy4gRWFjaCBjb2RlIGV4ZWN1dGlvbiBjYW4gZG8gYSBsb3QuIExldCBtZSB3cml0ZSBjb21wcmVoZW5zaXZlIHNjcmlwdHMgZm9yIGVhY2ggc3RhZ2UuXG5cblN0YWdlIDE6IFNjZW5lIHNldHVwIC0gY2xlYXIgZGVmYXVsdHMsIHNldCByZW5kZXIgc2V0dGluZ3MsIHNldCB1cCB3b3JsZFxuU3RhZ2UgMjogQnVpbGQgZW52aXJvbm1lbnQgLSB0YWJsZSwgYmFjayB3YWxsLCBkcmFwZXJ5IChDb3JuZWxsIGNvbG9ycylcblN0YWdlIDM6IE1vZGVsIFV0YWggVGVhcG90XG5TdGFnZSA0OiBNb2RlbCBTdGFuZm9yZCBCdW5ueVxuU3RhZ2UgNTogQWRkIFN1emFubmUgYXMgYnVzdFxuU3RhZ2UgNjogQ3JlYXRlIGNoZWNrZXJlZCByZWZsZWN0aXZlIHNwaGVyZVxuU3RhZ2UgNzogQWRkIHdpbmUgZ2xhc3MgKHN1cHBvcnRpbmcgcHJvcClcblN0YWdlIDg6IE1hdGVyaWFscyBmb3IgZXZlcnl0aGluZ1xuU3RhZ2UgOTogTGlnaHRpbmdcblN0YWdlIDEwOiBDYW1lcmEgc2V0dXBcblN0YWdlIDExOiBQcmV2aWV3IHJlbmRlciBhbmQgYWRqdXN0XG5cbkxldCBtZSBzdGFydC5cblxuQWN0dWFsbHksIGxldCBtZSByZWNvbnNpZGVyIHRoZSBhcHByb2FjaC4gSSB0aGluayBJIHNob3VsZDpcbjEuIEJ1aWxkIGFsbCBnZW9tZXRyeSBmaXJzdFxuMi4gVGhlbiBkbyBtYXRlcmlhbHNcbjMuIFRoZW4gbGlnaHRpbmcgYW5kIGNhbWVyYVxuNC4gVGhlbiBpdGVyYXRlIG9uIHRoZSByZW5kZXJcblxuQnV0IHNvbWUgdGhpbmdzIGFyZSBlYXNpZXIgdG8gZG8gdG9nZXRoZXIgKGdlb21ldHJ5ICsgbWF0ZXJpYWwpLiBMZXQgbWUgYmUgcHJhZ21hdGljLlxuXG5MZXQgbWUgc3RhcnQgd2l0aCBzY2VuZSBzZXR1cCBhbmQgZW52aXJvbm1lbnQuXG5cbkZvciB0aGUgY2xvdGgvZm9sZHMsIEkgY291bGQgdXNlIGEgcGxhbmUgd2l0aCBzdWJkaXZpc2lvbiBhbmQgc29tZSBkaXNwbGFjZW1lbnQsIG9yIEkgY291bGQgdXNlIGNsb3RoIHNpbXVsYXRpb24uIENsb3RoIHNpbXVsYXRpb24gbWlnaHQgYmUgY29tcGxleCB0byBjb250cm9sLiBMZXQgbWUgdXNlIGEgc3ViZGl2aWRlZCBwbGFuZSB3aXRoIG1hbnVhbCB2ZXJ0ZXggbWFuaXB1bGF0aW9uIG9yIGEgZGlzcGxhY2UgbW9kaWZpZXIgd2l0aCBhIG5vaXNlIHRleHR1cmUgdG8gY3JlYXRlIGZvbGRzLlxuXG5BY3R1YWxseSwgZm9yIHRoZSBkcmFwZXJ5LCBhIGdvb2QgYXBwcm9hY2ggaXM6XG4tIENyZWF0ZSBhIHBsYW5lLCBzdWJkaXZpZGUgaXQgaGVhdmlseVxuLSBVc2UgYSBEaXNwbGFjZSBtb2RpZmllciB3aXRoIGEgbm9pc2UgdGV4dHVyZSBmb3IgZm9sZCBzdHJ1Y3R1cmVcbi0gT3Igc2N1bHB0IGl0XG5cbkxldCBtZSB0aGluayBhYm91dCB3aGF0IHdpbGwgbG9vayBiZXN0IGFuZCBiZSBtb3N0IGNvbnRyb2xsYWJsZS4gSSB0aGluayBhIGNvbWJpbmF0aW9uIG9mIGEgc3ViZGl2aWRlZCBwbGFuZSB3aXRoIHNvbWUgbWFudWFsIHNoYXBpbmcgYW5kIGEgbm9pc2UgZGlzcGxhY2VtZW50IGNvdWxkIHdvcmsuIE9yIEkgY291bGQgdXNlIHRoZSBjbG90aCBzaW11bGF0b3IgdG8gZHJhcGUgYSBjbG90aCBvdmVyIHRoZSB0YWJsZSBlZGdlLlxuXG5MZXQgbWUgdHJ5IHRoZSBjbG90aCBzaW11bGF0aW9uIGFwcHJvYWNoIGZvciB0aGUgbWFpbiB0YWJsZWNsb3RoIC0gaXQgd291bGQgZ2l2ZSByZWFsaXN0aWMgZm9sZHMuIEJ1dCBJIG5lZWQgdG8gY29udHJvbCBpdCBjYXJlZnVsbHkuXG5cbkFjdHVhbGx5LCBmb3IgcmVsaWFiaWxpdHksIGxldCBtZSB1c2UgYSBzdWJkaXZpZGVkIG1lc2ggd2l0aCBjYXJlZnVsIHZlcnRleCBtYW5pcHVsYXRpb24gYW5kIGEgbm9pc2UgbW9kaWZpZXIuIFRoaXMgaXMgbW9yZSBwcmVkaWN0YWJsZSB0aGFuIHNpbXVsYXRpb24uXG5cbkhtbSwgbGV0IG1lIHJlY29uc2lkZXIuIEZvciBhIER1dGNoIHN0aWxsIGxpZmUsIHRoZSBjbG90aCBkcmFwZXJ5IGlzIGltcG9ydGFudC4gTGV0IG1lIHVzZSBhIHN1YmRpdmlkZWQgcGxhbmUgYW5kIHNjdWxwdC9zaGFwZSBpdCBtYW51YWxseSB3aXRoIGNvZGUgKG1vdmluZyB2ZXJ0aWNlcyksIHBsdXMgYSBub2lzZSBkaXNwbGFjZW1lbnQgZm9yIGZpbmUgZm9sZCBkZXRhaWwuXG5cbkxldCBtZSBzdGFydCBjb2RpbmcuXG5cbkxldCBtZSB0aGluayBhYm91dCB0aGUgb3ZlcmFsbCBzY2VuZSBsYXlvdXQ6XG5cbi0gVGFibGU6IGEgYm94LCByb3VnaGx5IDJtIHdpZGUsIDFtIGRlZXAsIGF0IGhlaWdodCB+MC43NW1cbi0gQmFjayB3YWxsOiBkYXJrLCBtYXliZSAzbSBiZWhpbmQgdGhlIHRhYmxlXG4tIFRhYmxlY2xvdGg6IGRyYXBpbmcgb3ZlciB0aGUgdGFibGUsIHdoaXRlL2dyZXkgbmV1dHJhbFxuLSBSZWQgY2xvdGg6IGRyYXBlZCBvbiB0aGUgbGVmdCBzaWRlXG4tIEdyZWVuIGNsb3RoIG9yIHdhbGwgcGFuZWw6IG9uIHRoZSByaWdodCBzaWRlXG5cbk9iamVjdHMgb24gdGhlIHRhYmxlIChmcm9tIGNhbWVyYSdzIHBlcnNwZWN0aXZlKTpcbi0gVGVhcG90OiBjZW50ZXIsIHNsaWdodGx5IGxlZnQsIGhlcm9cbi0gQnVubnk6IGJlaGluZCB0ZWFwb3QsIHNsaWdodGx5IHJpZ2h0XG4tIFN1emFubmU6IG9uIGEgc21hbGwgcGVkZXN0YWwsIHJpZ2h0IHNpZGVcbi0gQ2hlY2tlcmVkIHNwaGVyZTogZnJvbnQgbGVmdFxuLSBXaW5lIGdsYXNzOiByaWdodCBzaWRlLCB3aXRoIHJlZCB3aW5lXG5cbkNhbWVyYTogc2xpZ2h0bHkgZWxldmF0ZWQsIH41MG1tIGVxdWl2YWxlbnQsIGxvb2tpbmcgYXQgdGhlIGFycmFuZ2VtZW50XG5cbkxpZ2h0OiB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgKHdpbmRvdyBzaGFmdCksIG1heWJlIGEgc3BvdCBsaWdodCBvciBhcmVhIGxpZ2h0XG5cbkxldCBtZSBzdGFydCBidWlsZGluZy5cblxuRm9yIHRoZSBmaXJzdCBjb2RlIGJsb2NrLCBsZXQgbWU6XG4xLiBDbGVhciB0aGUgc2NlbmVcbjIuIFNldCB1cCBDeWNsZXMgcmVuZGVyIHNldHRpbmdzXG4zLiBTZXQgdXAgdGhlIHdvcmxkIGJhY2tncm91bmQgKGRhcmspXG40LiBTZXQgY29sb3IgbWFuYWdlbWVudFxuXG5MZXQgbWUgZ28uXG5cbkFjdHVhbGx5LCBJIHNob3VsZCBhbHNvIHRoaW5rIGFib3V0IHdoYXQgXCI1MG1tIGVxdWl2YWxlbnRcIiBtZWFucy4gT24gYSBmdWxsLWZyYW1lIHNlbnNvciAoMzZtbSB4IDI0bW0pLCBhIDUwbW0gbGVucyBoYXMgYSBob3Jpem9udGFsIEZPViBvZiBhYm91dCAzOS42IGRlZ3JlZXMuIEluIEJsZW5kZXIsIHRoZSBkZWZhdWx0IHNlbnNvciBzaXplIGlzIDM2bW0uIFNvIEkgc2hvdWxkIHNldCB0aGUgY2FtZXJhIGZvY2FsIGxlbmd0aCB0byA1MG1tIHdpdGggYSAzNm1tIHNlbnNvci5cblxuTGV0IG1lIHN0YXJ0IHdpdGggdGhlIHNjZW5lIHNldHVwLlxuXG5MZXQgbWUgd3JpdGUgbXkgZmlyc3QgY29kZSBibG9jayB0byBzZXQgdXAgdGhlIHNjZW5lLlxuXG5JJ2xsIHN0YXJ0IHNpbXBsZSBhbmQgYnVpbGQgdXAuIExldCBtZSBjbGVhciBldmVyeXRoaW5nIGFuZCBzZXQgdXAgdGhlIGJhc2ljcy5cblxuRm9yIHRoaXMgZmlyc3Qgc3RlcCwgbGV0IG1lOlxuMS4gRGVsZXRlIGFsbCBleGlzdGluZyBvYmplY3RzXG4yLiBTZXQgcmVuZGVyIGVuZ2luZSB0byBDeWNsZXNcbjMuIFNldCByZW5kZXIgcmVzb2x1dGlvblxuNC4gU2V0IGNvbG9yIG1hbmFnZW1lbnQgdG8gRmlsbWljXG41LiBTZXQgd29ybGQgdG8gZGFya1xuXG5MZXQgbWUgZ28uXG5cbkkgdGhpbmsgSSBzaG91bGQgYWxzbyBwbGFuIHRoZSBtYXRlcmlhbHMuIExldCBtZSB0aGluayBhYm91dCB3aGF0IHNoYWRlcnMgSSdsbCBuZWVkOlxuXG4xLiBTaWx2ZXIvcGV3dGVyIHRlYXBvdDogUHJpbmNpcGxlZCBCU0RGLCBoaWdoIG1ldGFsbGljLCByb3VnaG5lc3MgfjAuMy0wLjQsIHNsaWdodGx5IHRpbnRlZFxuMi4gQnJvbnplIGJ1bm55OiBQcmluY2lwbGVkIEJTREYsIG1ldGFsbGljLCBjb3BwZXIvYnJvbnplIGNvbG9yXG4zLiBNYXJibGUgU3V6YW5uZTogUHJpbmNpcGxlZCBCU0RGLCB3aGl0ZS9ncmV5LCBsb3cgcm91Z2huZXNzLCBtYXliZSBzdWJzdXJmYWNlXG40LiBDaGVja2VyZWQgY2hyb21lIHNwaGVyZTogR2xvc3N5IEJTREYgd2l0aCBjaGVja2VyIHRleHR1cmUgKG1peCBvZiB0d28gY29sb3JzLCBvbmUgcmVmbGVjdGl2ZSlcbjUuIFdpbmUgZ2xhc3M6IEdsYXNzIEJTREZcbjYuIFdpbmU6IGRhcmsgcmVkLCBzbGlnaHRseSB0cmFuc3BhcmVudFxuNy4gVmVsdmV0IGNsb3RoOiBQcmluY2lwbGVkIEJTREYgd2l0aCBzaGVlbiwgb3IgYSB2ZWx2ZXQgc2hhZGVyXG44LiBXb29kIHRhYmxlOiBQcmluY2lwbGVkIEJTREYgd2l0aCB3b29kIHRleHR1cmVcbjkuIFdhbGw6IGRhcmssIHNsaWdodGx5IHRleHR1cmVkXG5cbkxldCBtZSBzdGFydCBidWlsZGluZy4gSSdsbCBkbyB0aGUgZW52aXJvbm1lbnQgZmlyc3QuXG5cbkxldCBtZSB3cml0ZSB0aGUgY29kZSBmb3Igc2NlbmUgc2V0dXAgYW5kIGVudmlyb25tZW50LlxuXG5JJ2xsIHRoaW5rIGFib3V0IHRoaXMgbW9yZSBjYXJlZnVsbHkgYXMgSSBnby4gTGV0IG1lIHN0YXJ0LlxuXG5MZXQgbWUgdGhpbmsgYWJvdXQgdGhlIGRpbWVuc2lvbnMuIEknbGwgdXNlIGEgc2NhbGUgd2hlcmUgdGhlIHRhYmxlIGlzIGFib3V0IDEuNW0gd2lkZS5cblxuVGFibGU6IDEuNW0geCAwLjhtLCBoZWlnaHQgMC43NW1cblRlYXBvdDogYWJvdXQgMC4ybSB0YWxsXG5CdW5ueTogYWJvdXQgMC4xNW0gdGFsbFxuU3V6YW5uZTogZGVmYXVsdCBzaXplLCBhYm91dCAwLjJtXG5TcGhlcmU6IDAuMW0gcmFkaXVzXG5XaW5lIGdsYXNzOiBhYm91dCAwLjJtIHRhbGxcblxuQ2FtZXJhOiBhYm91dCAxLjJtIGhpZ2gsIDFtIGJhY2sgZnJvbSB0YWJsZSBlZGdlLCBsb29raW5nIGF0IHRoZSBhcnJhbmdlbWVudFxuXG5MZXQgbWUgc3RhcnQgY29kaW5nIG5vdy4gSSdsbCBkbyB0aGUgc2NlbmUgc2V0dXAgZmlyc3QuXG5cbkxldCBtZSB0aGluayBzdGVwIGJ5IHN0ZXAgYWJvdXQgd2hhdCB0byBkbyBmaXJzdDpcblxuMS4gQ2xlYXIgc2NlbmVcbjIuIFNldCB1cCByZW5kZXIgc2V0dGluZ3MgKEN5Y2xlcywgRmlsbWljLCBldGMuKVxuMy4gQnVpbGQgdGhlIGVudmlyb25tZW50OiB0YWJsZSwgd2FsbHMsIGNsb3RoXG40LiBCdWlsZCBlYWNoIG9iamVjdFxuNS4gQXBwbHkgbWF0ZXJpYWxzXG42LiBTZXQgdXAgbGlnaHRpbmdcbjcuIFNldCB1cCBjYW1lcmFcbjguIFByZXZpZXcgcmVuZGVyIGFuZCBpdGVyYXRlXG5cbkxldCBtZSBiZWdpbiB3aXRoIHN0ZXAgMS0yLiIsImZvcm1hdCI6InVua25vd24iLCJpbmRleCI6MH1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo1MDYzLCJjb21wbGV0aW9uX3Rva2VucyI6MjQ3MCwidG90YWxfdG9rZW5zIjo3NTMzLCJjb3N0IjowLjAxMjAxMjY5NzgsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMTIwMTI2OTc4LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA0NzQyMDA1OCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDA3MjcwNjkyfSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjoyNTAyLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "name": "get_blendfile_summary_datablocks", "arguments": {}, "raw_arguments": "{}", "parse_error": null}, {"id": "chatcmpl-tool-945d697d0850e4b7", "name": "get_objects_summary", "arguments": {}, "raw_arguments": "{}", "parse_error": null}], "tokens_in": 5063, "tokens_out": 2470, "cost_usd": 0.0120126978, "cached_tokens": 0}, "error": null}
{"ts": "2026-07-17T14:53:26.343130+00:00", "type": "assistant", "text": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "name": "get_blendfile_summary_datablocks", "arguments": {}, "raw_arguments": "{}", "parse_error": null}, {"id": "chatcmpl-tool-945d697d0850e4b7", "name": "get_objects_summary", "arguments": {}, "raw_arguments": "{}", "parse_error": null}]}
{"ts": "2026-07-17T14:53:26.343130+00:00", "type": "tool_call", "id": "chatcmpl-tool-aadef2b898f113d4", "name": "get_blendfile_summary_datablocks", "arguments": {}, "raw_arguments": "{}"}
{"ts": "2026-07-17T14:53:27.125287+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "name": "get_blendfile_summary_datablocks", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:53:27.125287+00:00", "type": "tool_call", "id": "chatcmpl-tool-945d697d0850e4b7", "name": "get_objects_summary", "arguments": {}, "raw_arguments": "{}"}
{"ts": "2026-07-17T14:53:27.153594+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "name": "get_objects_summary", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:54:14.795170+00:00", "type": "llm_call", "call_index": 2, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:53:27.153594+00:00", "finished_at": "2026-07-17T14:54:14.795170+00:00", "duration_s": 47.64100000000326, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:53:27.153594+00:00", "finished_at": "2026-07-17T14:54:14.795170+00:00", "duration_s": 47.64100000000326, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "23595", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:53:29 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300007-uCS6rfrIdhx1zpG4xd9K", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca13884b28038f-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300007-uCS6rfrIdhx1zpG4xd9K\",\"object\":\"chat.completion\",\"created\":1784300008,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"refusal\":null,\"reasoning\":\"The scene starts essentially empty. Let me plan out my approach:\\n\\n1. Set up Cycles render engine with proper color management\\n2. Build the table and background (Cornell box palette - red and green cloths/walls)\\n3. Model the Utah Teapot (classic squat proportions)\\n4. Model the Stanford Bunny (approximate crouched rabbit)\\n5. Add Suzanne (built-in Blender monkey head)\\n6. Create the reflective checkered sphere\\n7. Add a classical prop (wine glass or fruit)\\n8. Set up chiaroscuro lighting (single warm light source)\\n9. Set up camera at slightly elevated angle, ~50mm equivalent\\n10. Apply materials (ceramic/silver teapot, patinated metal, velvet cloth, polished chrome sphere)\\n\\nLet me start by clearing the scene and setting up the render engine and basic environment.\\n\\nI'll work step by step. First, let me set up the scene foundation - render settings, world, table, and background.\\n\\nLet me think about the Cornell box palette integration:\\n- A red draped cloth on one side\\n- A green draped cloth on the other side\\n- Neutral white/grey table/elements between\\n\\nLet me think about the composition:\\n- Table edge in lower frame\\n- Teapot commanding the arrangement (center-ish, hero)\\n- Objects grouped in overlapping depth\\n- Camera at slightly elevated angle, ~50mm equivalent\\n\\nLet me think about the Utah Teapot geometry. The classic Utah teapot has:\\n- A squat, rounded body (like a slightly flattened sphere)\\n- A spout on one side (curved, like a tube that curves up and out)\\n- A handle on the other side (curved tube)\\n- A lid on top with a small knob\\n\\nI'll model this with bezier curves and surface/solid operations, or use mesh modeling.\\n\\nActually, for the teapot, I can use a combination of:\\n- Body: a lathe/revolved profile (use a bezier curve with bevel, or use a mesh from spin)\\n- Spout: a curved tube\\n- Handle: a curved torus-like tube\\n- Lid: a smaller revolved shape with a knob\\n\\nLet me think about how to do this with code in Blender. I can use bmesh or direct mesh creation.\\n\\nFor the teapot, the cleanest approach in code:\\n- Use bezier curves with bevel/extrude for the body (revolved profile), spout, handle\\n- Convert to mesh\\n\\nActually, let me use a combination of primitives and modeling. Let me write Python code.\\n\\nFor the Stanford Bunny approximation, I'll need to sculpt/model a crouched rabbit. This is tricky in code. I could use metaballs to approximate the blobby organic form, or use mesh manipulation. A metaball approach might give a nice sculptural feel. Or I could build it from primitive spheres and merge them.\\n\\nLet me think about the bunny shape:\\n- Rounded body (crouched, compact)\\n- Head tucked down\\n- Folded ears (two elongated shapes along the back)\\n- It's a crouched rabbit viewed from the side mostly\\n\\nI'll build it from metaballs - a few spheres for the body, head, and elongated shapes for ears. That would give a smooth sculptural form.\\n\\nActually, metaballs in Blender render nicely and would give the organic sculpted look. Let me use that for the bunny.\\n\\nFor Suzanne, I can just add the built-in monkey mesh.\\n\\nFor the checkered sphere, I'll add a UV sphere with a checkered material (using procedural texture or checker pattern in shader).\\n\\nFor the classical prop, let me do a wine glass (can be built from a revolved profile) and maybe some fruit (apples/oranges from spheres with materials).\\n\\nLet me start coding. I'll do this in stages:\\n\\nStage 1: Scene setup - render engine, color management, world, camera basics\\nStage 2: Table and background structure (Cornell palette cloths)\\nStage 3: Utah Teapot\\nStage 4: Stanford Bunny (metaballs)\\nStage 5: Suzanne\\nStage 6: Checkered sphere\\nStage 7: Wine glass + fruit\\nStage 8: Lighting (chiaroscuro)\\nStage 9: Camera setup\\nStage 10: Materials refinement\\nStage 11: Preview renders and adjustments\\n\\nLet me begin.\\n\\nI'll write the code in chunks. Let me start with scene setup and the table/background.\\n\\nFor the Dutch still life, the background should be dark. I'll create:\\n- A table top (a box/plane)\\n- A back wall (dark)\\n- Draped cloths - one red, one green (the Cornell nod)\\n\\nLet me think about the cloth. For real fold structure, I could use a subdivided plane with displacement, or model folds. A simpler approach that looks good: use a subdivided plane with some noise/displacement and cloth-like shading. But modeling actual draped folds in code is hard.\\n\\nA good approach: create a plane, subdivide it heavily, then apply a wave/noise displacement to create fold-like undulations. Or I could model the cloth as a curved surface with manual fold shapes.\\n\\nActually, for a draped cloth on the table, I can create a subdivided plane and use a Displace modifier with a noise texture, plus sculpt some folds. But in code, let me use bmesh to create undulating folds.\\n\\nLet me think simpler but effective: I'll create the cloth as a subdivided mesh and apply some sinusoidal displacement to create fold ridges, then give it a velvet material.\\n\\nLet me start coding. I'll do the scene setup first.\\n\\nLet me be careful about the approach. I'll write comprehensive Python code that builds the scene. Let me start with the foundation.\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The scene starts essentially empty. Let me plan out my approach:\\n\\n1. Set up Cycles render engine with proper color management\\n2. Build the table and background (Cornell box palette - red and green cloths/walls)\\n3. Model the Utah Teapot (classic squat proportions)\\n4. Model the Stanford Bunny (approximate crouched rabbit)\\n5. Add Suzanne (built-in Blender monkey head)\\n6. Create the reflective checkered sphere\\n7. Add a classical prop (wine glass or fruit)\\n8. Set up chiaroscuro lighting (single warm light source)\\n9. Set up camera at slightly elevated angle, ~50mm equivalent\\n10. Apply materials (ceramic/silver teapot, patinated metal, velvet cloth, polished chrome sphere)\\n\\nLet me start by clearing the scene and setting up the render engine and basic environment.\\n\\nI'll work step by step. First, let me set up the scene foundation - render settings, world, table, and background.\\n\\nLet me think about the Cornell box palette integration:\\n- A red draped cloth on one side\\n- A green draped cloth on the other side\\n- Neutral white/grey table/elements between\\n\\nLet me think about the composition:\\n- Table edge in lower frame\\n- Teapot commanding the arrangement (center-ish, hero)\\n- Objects grouped in overlapping depth\\n- Camera at slightly elevated angle, ~50mm equivalent\\n\\nLet me think about the Utah Teapot geometry. The classic Utah teapot has:\\n- A squat, rounded body (like a slightly flattened sphere)\\n- A spout on one side (curved, like a tube that curves up and out)\\n- A handle on the other side (curved tube)\\n- A lid on top with a small knob\\n\\nI'll model this with bezier curves and surface/solid operations, or use mesh modeling.\\n\\nActually, for the teapot, I can use a combination of:\\n- Body: a lathe/revolved profile (use a bezier curve with bevel, or use a mesh from spin)\\n- Spout: a curved tube\\n- Handle: a curved torus-like tube\\n- Lid: a smaller revolved shape with a knob\\n\\nLet me think about how to do this with code in Blender. I can use bmesh or direct mesh creation.\\n\\nFor the teapot, the cleanest approach in code:\\n- Use bezier curves with bevel/extrude for the body (revolved profile), spout, handle\\n- Convert to mesh\\n\\nActually, let me use a combination of primitives and modeling. Let me write Python code.\\n\\nFor the Stanford Bunny approximation, I'll need to sculpt/model a crouched rabbit. This is tricky in code. I could use metaballs to approximate the blobby organic form, or use mesh manipulation. A metaball approach might give a nice sculptural feel. Or I could build it from primitive spheres and merge them.\\n\\nLet me think about the bunny shape:\\n- Rounded body (crouched, compact)\\n- Head tucked down\\n- Folded ears (two elongated shapes along the back)\\n- It's a crouched rabbit viewed from the side mostly\\n\\nI'll build it from metaballs - a few spheres for the body, head, and elongated shapes for ears. That would give a smooth sculptural form.\\n\\nActually, metaballs in Blender render nicely and would give the organic sculpted look. Let me use that for the bunny.\\n\\nFor Suzanne, I can just add the built-in monkey mesh.\\n\\nFor the checkered sphere, I'll add a UV sphere with a checkered material (using procedural texture or checker pattern in shader).\\n\\nFor the classical prop, let me do a wine glass (can be built from a revolved profile) and maybe some fruit (apples/oranges from spheres with materials).\\n\\nLet me start coding. I'll do this in stages:\\n\\nStage 1: Scene setup - render engine, color management, world, camera basics\\nStage 2: Table and background structure (Cornell palette cloths)\\nStage 3: Utah Teapot\\nStage 4: Stanford Bunny (metaballs)\\nStage 5: Suzanne\\nStage 6: Checkered sphere\\nStage 7: Wine glass + fruit\\nStage 8: Lighting (chiaroscuro)\\nStage 9: Camera setup\\nStage 10: Materials refinement\\nStage 11: Preview renders and adjustments\\n\\nLet me begin.\\n\\nI'll write the code in chunks. Let me start with scene setup and the table/background.\\n\\nFor the Dutch still life, the background should be dark. I'll create:\\n- A table top (a box/plane)\\n- A back wall (dark)\\n- Draped cloths - one red, one green (the Cornell nod)\\n\\nLet me think about the cloth. For real fold structure, I could use a subdivided plane with displacement, or model folds. A simpler approach that looks good: use a subdivided plane with some noise/displacement and cloth-like shading. But modeling actual draped folds in code is hard.\\n\\nA good approach: create a plane, subdivide it heavily, then apply a wave/noise displacement to create fold-like undulations. Or I could model the cloth as a curved surface with manual fold shapes.\\n\\nActually, for a draped cloth on the table, I can create a subdivided plane and use a Displace modifier with a noise texture, plus sculpt some folds. But in code, let me use bmesh to create undulating folds.\\n\\nLet me think simpler but effective: I'll create the cloth as a subdivided mesh and apply some sinusoidal displacement to create fold ridges, then give it a velvet material.\\n\\nLet me start coding. I'll do the scene setup first.\\n\\nLet me be careful about the approach. I'll write comprehensive Python code that builds the scene. Let me start with the foundation.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":5525,\"completion_tokens\":1726,\"total_tokens\":7251,\"cost\":0.00639935964,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":5056,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00639935964,\"upstream_inference_prompt_cost\":0.00131870604,\"upstream_inference_completions_cost\":0.0050806536},\"completion_tokens_details\":{\"reasoning_tokens\":1301,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDAwMDctdUNTNnJmcklkaHgxenBHNHhkOUsiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwMDA4LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOiJUaGUgc2NlbmUgc3RhcnRzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBvdXQgbXkgYXBwcm9hY2g6XG5cbjEuIFNldCB1cCBDeWNsZXMgcmVuZGVyIGVuZ2luZSB3aXRoIHByb3BlciBjb2xvciBtYW5hZ2VtZW50XG4yLiBCdWlsZCB0aGUgdGFibGUgYW5kIGJhY2tncm91bmQgKENvcm5lbGwgYm94IHBhbGV0dGUgLSByZWQgYW5kIGdyZWVuIGNsb3Rocy93YWxscylcbjMuIE1vZGVsIHRoZSBVdGFoIFRlYXBvdCAoY2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucylcbjQuIE1vZGVsIHRoZSBTdGFuZm9yZCBCdW5ueSAoYXBwcm94aW1hdGUgY3JvdWNoZWQgcmFiYml0KVxuNS4gQWRkIFN1emFubmUgKGJ1aWx0LWluIEJsZW5kZXIgbW9ua2V5IGhlYWQpXG42LiBDcmVhdGUgdGhlIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZVxuNy4gQWRkIGEgY2xhc3NpY2FsIHByb3AgKHdpbmUgZ2xhc3Mgb3IgZnJ1aXQpXG44LiBTZXQgdXAgY2hpYXJvc2N1cm8gbGlnaHRpbmcgKHNpbmdsZSB3YXJtIGxpZ2h0IHNvdXJjZSlcbjkuIFNldCB1cCBjYW1lcmEgYXQgc2xpZ2h0bHkgZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcbjEwLiBBcHBseSBtYXRlcmlhbHMgKGNlcmFtaWMvc2lsdmVyIHRlYXBvdCwgcGF0aW5hdGVkIG1ldGFsLCB2ZWx2ZXQgY2xvdGgsIHBvbGlzaGVkIGNocm9tZSBzcGhlcmUpXG5cbkxldCBtZSBzdGFydCBieSBjbGVhcmluZyB0aGUgc2NlbmUgYW5kIHNldHRpbmcgdXAgdGhlIHJlbmRlciBlbmdpbmUgYW5kIGJhc2ljIGVudmlyb25tZW50LlxuXG5JJ2xsIHdvcmsgc3RlcCBieSBzdGVwLiBGaXJzdCwgbGV0IG1lIHNldCB1cCB0aGUgc2NlbmUgZm91bmRhdGlvbiAtIHJlbmRlciBzZXR0aW5ncywgd29ybGQsIHRhYmxlLCBhbmQgYmFja2dyb3VuZC5cblxuTGV0IG1lIHRoaW5rIGFib3V0IHRoZSBDb3JuZWxsIGJveCBwYWxldHRlIGludGVncmF0aW9uOlxuLSBBIHJlZCBkcmFwZWQgY2xvdGggb24gb25lIHNpZGVcbi0gQSBncmVlbiBkcmFwZWQgY2xvdGggb24gdGhlIG90aGVyIHNpZGVcbi0gTmV1dHJhbCB3aGl0ZS9ncmV5IHRhYmxlL2VsZW1lbnRzIGJldHdlZW5cblxuTGV0IG1lIHRoaW5rIGFib3V0IHRoZSBjb21wb3NpdGlvbjpcbi0gVGFibGUgZWRnZSBpbiBsb3dlciBmcmFtZVxuLSBUZWFwb3QgY29tbWFuZGluZyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1pc2gsIGhlcm8pXG4tIE9iamVjdHMgZ3JvdXBlZCBpbiBvdmVybGFwcGluZyBkZXB0aFxuLSBDYW1lcmEgYXQgc2xpZ2h0bHkgZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcblxuTGV0IG1lIHRoaW5rIGFib3V0IHRoZSBVdGFoIFRlYXBvdCBnZW9tZXRyeS4gVGhlIGNsYXNzaWMgVXRhaCB0ZWFwb3QgaGFzOlxuLSBBIHNxdWF0LCByb3VuZGVkIGJvZHkgKGxpa2UgYSBzbGlnaHRseSBmbGF0dGVuZWQgc3BoZXJlKVxuLSBBIHNwb3V0IG9uIG9uZSBzaWRlIChjdXJ2ZWQsIGxpa2UgYSB0dWJlIHRoYXQgY3VydmVzIHVwIGFuZCBvdXQpXG4tIEEgaGFuZGxlIG9uIHRoZSBvdGhlciBzaWRlIChjdXJ2ZWQgdHViZSlcbi0gQSBsaWQgb24gdG9wIHdpdGggYSBzbWFsbCBrbm9iXG5cbkknbGwgbW9kZWwgdGhpcyB3aXRoIGJlemllciBjdXJ2ZXMgYW5kIHN1cmZhY2Uvc29saWQgb3BlcmF0aW9ucywgb3IgdXNlIG1lc2ggbW9kZWxpbmcuXG5cbkFjdHVhbGx5LCBmb3IgdGhlIHRlYXBvdCwgSSBjYW4gdXNlIGEgY29tYmluYXRpb24gb2Y6XG4tIEJvZHk6IGEgbGF0aGUvcmV2b2x2ZWQgcHJvZmlsZSAodXNlIGEgYmV6aWVyIGN1cnZlIHdpdGggYmV2ZWwsIG9yIHVzZSBhIG1lc2ggZnJvbSBzcGluKVxuLSBTcG91dDogYSBjdXJ2ZWQgdHViZVxuLSBIYW5kbGU6IGEgY3VydmVkIHRvcnVzLWxpa2UgdHViZVxuLSBMaWQ6IGEgc21hbGxlciByZXZvbHZlZCBzaGFwZSB3aXRoIGEga25vYlxuXG5MZXQgbWUgdGhpbmsgYWJvdXQgaG93IHRvIGRvIHRoaXMgd2l0aCBjb2RlIGluIEJsZW5kZXIuIEkgY2FuIHVzZSBibWVzaCBvciBkaXJlY3QgbWVzaCBjcmVhdGlvbi5cblxuRm9yIHRoZSB0ZWFwb3QsIHRoZSBjbGVhbmVzdCBhcHByb2FjaCBpbiBjb2RlOlxuLSBVc2UgYmV6aWVyIGN1cnZlcyB3aXRoIGJldmVsL2V4dHJ1ZGUgZm9yIHRoZSBib2R5IChyZXZvbHZlZCBwcm9maWxlKSwgc3BvdXQsIGhhbmRsZVxuLSBDb252ZXJ0IHRvIG1lc2hcblxuQWN0dWFsbHksIGxldCBtZSB1c2UgYSBjb21iaW5hdGlvbiBvZiBwcmltaXRpdmVzIGFuZCBtb2RlbGluZy4gTGV0IG1lIHdyaXRlIFB5dGhvbiBjb2RlLlxuXG5Gb3IgdGhlIFN0YW5mb3JkIEJ1bm55IGFwcHJveGltYXRpb24sIEknbGwgbmVlZCB0byBzY3VscHQvbW9kZWwgYSBjcm91Y2hlZCByYWJiaXQuIFRoaXMgaXMgdHJpY2t5IGluIGNvZGUuIEkgY291bGQgdXNlIG1ldGFiYWxscyB0byBhcHByb3hpbWF0ZSB0aGUgYmxvYmJ5IG9yZ2FuaWMgZm9ybSwgb3IgdXNlIG1lc2ggbWFuaXB1bGF0aW9uLiBBIG1ldGFiYWxsIGFwcHJvYWNoIG1pZ2h0IGdpdmUgYSBuaWNlIHNjdWxwdHVyYWwgZmVlbC4gT3IgSSBjb3VsZCBidWlsZCBpdCBmcm9tIHByaW1pdGl2ZSBzcGhlcmVzIGFuZCBtZXJnZSB0aGVtLlxuXG5MZXQgbWUgdGhpbmsgYWJvdXQgdGhlIGJ1bm55IHNoYXBlOlxuLSBSb3VuZGVkIGJvZHkgKGNyb3VjaGVkLCBjb21wYWN0KVxuLSBIZWFkIHR1Y2tlZCBkb3duXG4tIEZvbGRlZCBlYXJzICh0d28gZWxvbmdhdGVkIHNoYXBlcyBhbG9uZyB0aGUgYmFjaylcbi0gSXQncyBhIGNyb3VjaGVkIHJhYmJpdCB2aWV3ZWQgZnJvbSB0aGUgc2lkZSBtb3N0bHlcblxuSSdsbCBidWlsZCBpdCBmcm9tIG1ldGFiYWxscyAtIGEgZmV3IHNwaGVyZXMgZm9yIHRoZSBib2R5LCBoZWFkLCBhbmQgZWxvbmdhdGVkIHNoYXBlcyBmb3IgZWFycy4gVGhhdCB3b3VsZCBnaXZlIGEgc21vb3RoIHNjdWxwdHVyYWwgZm9ybS5cblxuQWN0dWFsbHksIG1ldGFiYWxscyBpbiBCbGVuZGVyIHJlbmRlciBuaWNlbHkgYW5kIHdvdWxkIGdpdmUgdGhlIG9yZ2FuaWMgc2N1bHB0ZWQgbG9vay4gTGV0IG1lIHVzZSB0aGF0IGZvciB0aGUgYnVubnkuXG5cbkZvciBTdXphbm5lLCBJIGNhbiBqdXN0IGFkZCB0aGUgYnVpbHQtaW4gbW9ua2V5IG1lc2guXG5cbkZvciB0aGUgY2hlY2tlcmVkIHNwaGVyZSwgSSdsbCBhZGQgYSBVViBzcGhlcmUgd2l0aCBhIGNoZWNrZXJlZCBtYXRlcmlhbCAodXNpbmcgcHJvY2VkdXJhbCB0ZXh0dXJlIG9yIGNoZWNrZXIgcGF0dGVybiBpbiBzaGFkZXIpLlxuXG5Gb3IgdGhlIGNsYXNzaWNhbCBwcm9wLCBsZXQgbWUgZG8gYSB3aW5lIGdsYXNzIChjYW4gYmUgYnVpbHQgZnJvbSBhIHJldm9sdmVkIHByb2ZpbGUpIGFuZCBtYXliZSBzb21lIGZydWl0IChhcHBsZXMvb3JhbmdlcyBmcm9tIHNwaGVyZXMgd2l0aCBtYXRlcmlhbHMpLlxuXG5MZXQgbWUgc3RhcnQgY29kaW5nLiBJJ2xsIGRvIHRoaXMgaW4gc3RhZ2VzOlxuXG5TdGFnZSAxOiBTY2VuZSBzZXR1cCAtIHJlbmRlciBlbmdpbmUsIGNvbG9yIG1hbmFnZW1lbnQsIHdvcmxkLCBjYW1lcmEgYmFzaWNzXG5TdGFnZSAyOiBUYWJsZSBhbmQgYmFja2dyb3VuZCBzdHJ1Y3R1cmUgKENvcm5lbGwgcGFsZXR0ZSBjbG90aHMpXG5TdGFnZSAzOiBVdGFoIFRlYXBvdFxuU3RhZ2UgNDogU3RhbmZvcmQgQnVubnkgKG1ldGFiYWxscylcblN0YWdlIDU6IFN1emFubmVcblN0YWdlIDY6IENoZWNrZXJlZCBzcGhlcmVcblN0YWdlIDc6IFdpbmUgZ2xhc3MgKyBmcnVpdFxuU3RhZ2UgODogTGlnaHRpbmcgKGNoaWFyb3NjdXJvKVxuU3RhZ2UgOTogQ2FtZXJhIHNldHVwXG5TdGFnZSAxMDogTWF0ZXJpYWxzIHJlZmluZW1lbnRcblN0YWdlIDExOiBQcmV2aWV3IHJlbmRlcnMgYW5kIGFkanVzdG1lbnRzXG5cbkxldCBtZSBiZWdpbi5cblxuSSdsbCB3cml0ZSB0aGUgY29kZSBpbiBjaHVua3MuIExldCBtZSBzdGFydCB3aXRoIHNjZW5lIHNldHVwIGFuZCB0aGUgdGFibGUvYmFja2dyb3VuZC5cblxuRm9yIHRoZSBEdXRjaCBzdGlsbCBsaWZlLCB0aGUgYmFja2dyb3VuZCBzaG91bGQgYmUgZGFyay4gSSdsbCBjcmVhdGU6XG4tIEEgdGFibGUgdG9wIChhIGJveC9wbGFuZSlcbi0gQSBiYWNrIHdhbGwgKGRhcmspXG4tIERyYXBlZCBjbG90aHMgLSBvbmUgcmVkLCBvbmUgZ3JlZW4gKHRoZSBDb3JuZWxsIG5vZClcblxuTGV0IG1lIHRoaW5rIGFib3V0IHRoZSBjbG90aC4gRm9yIHJlYWwgZm9sZCBzdHJ1Y3R1cmUsIEkgY291bGQgdXNlIGEgc3ViZGl2aWRlZCBwbGFuZSB3aXRoIGRpc3BsYWNlbWVudCwgb3IgbW9kZWwgZm9sZHMuIEEgc2ltcGxlciBhcHByb2FjaCB0aGF0IGxvb2tzIGdvb2Q6IHVzZSBhIHN1YmRpdmlkZWQgcGxhbmUgd2l0aCBzb21lIG5vaXNlL2Rpc3BsYWNlbWVudCBhbmQgY2xvdGgtbGlrZSBzaGFkaW5nLiBCdXQgbW9kZWxpbmcgYWN0dWFsIGRyYXBlZCBmb2xkcyBpbiBjb2RlIGlzIGhhcmQuXG5cbkEgZ29vZCBhcHByb2FjaDogY3JlYXRlIGEgcGxhbmUsIHN1YmRpdmlkZSBpdCBoZWF2aWx5LCB0aGVuIGFwcGx5IGEgd2F2ZS9ub2lzZSBkaXNwbGFjZW1lbnQgdG8gY3JlYXRlIGZvbGQtbGlrZSB1bmR1bGF0aW9ucy4gT3IgSSBjb3VsZCBtb2RlbCB0aGUgY2xvdGggYXMgYSBjdXJ2ZWQgc3VyZmFjZSB3aXRoIG1hbnVhbCBmb2xkIHNoYXBlcy5cblxuQWN0dWFsbHksIGZvciBhIGRyYXBlZCBjbG90aCBvbiB0aGUgdGFibGUsIEkgY2FuIGNyZWF0ZSBhIHN1YmRpdmlkZWQgcGxhbmUgYW5kIHVzZSBhIERpc3BsYWNlIG1vZGlmaWVyIHdpdGggYSBub2lzZSB0ZXh0dXJlLCBwbHVzIHNjdWxwdCBzb21lIGZvbGRzLiBCdXQgaW4gY29kZSwgbGV0IG1lIHVzZSBibWVzaCB0byBjcmVhdGUgdW5kdWxhdGluZyBmb2xkcy5cblxuTGV0IG1lIHRoaW5rIHNpbXBsZXIgYnV0IGVmZmVjdGl2ZTogSSdsbCBjcmVhdGUgdGhlIGNsb3RoIGFzIGEgc3ViZGl2aWRlZCBtZXNoIGFuZCBhcHBseSBzb21lIHNpbnVzb2lkYWwgZGlzcGxhY2VtZW50IHRvIGNyZWF0ZSBmb2xkIHJpZGdlcywgdGhlbiBnaXZlIGl0IGEgdmVsdmV0IG1hdGVyaWFsLlxuXG5MZXQgbWUgc3RhcnQgY29kaW5nLiBJJ2xsIGRvIHRoZSBzY2VuZSBzZXR1cCBmaXJzdC5cblxuTGV0IG1lIGJlIGNhcmVmdWwgYWJvdXQgdGhlIGFwcHJvYWNoLiBJJ2xsIHdyaXRlIGNvbXByZWhlbnNpdmUgUHl0aG9uIGNvZGUgdGhhdCBidWlsZHMgdGhlIHNjZW5lLiBMZXQgbWUgc3RhcnQgd2l0aCB0aGUgZm91bmRhdGlvbi4iLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWJlMzI3NGRjNjI2MDJhYmUiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyAtLS0gQ2xlYXIgdGhlIHNjZW5lIC0tLVxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbmJweS5vcHMub2JqZWN0LmRlbGV0ZSh1c2VfZ2xvYmFsPUZhbHNlLCBjb25maXJtPUZhbHNlKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLm1lc2hlcyk6XFxuICAgIGJweS5kYXRhLm1lc2hlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWF0ZXJpYWxzKTpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jdXJ2ZXMpOlxcbiAgICBicHkuZGF0YS5jdXJ2ZXMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmxpZ2h0cyk6XFxuICAgIGJweS5kYXRhLmxpZ2h0cy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuY2FtZXJhcyk6XFxuICAgIGJweS5kYXRhLmNhbWVyYXMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmltYWdlcyk6XFxuICAgIGJweS5kYXRhLmltYWdlcy5yZW1vdmUoYmxvY2spXFxuXFxuIyAtLS0gUmVuZGVyIHNldHRpbmdzOiBDeWNsZXMgLS0tXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLnJlbmRlci5lbmdpbmUgPSAnQ1lDTEVTJ1xcbnNjZW5lLmN5Y2xlcy5kZXZpY2UgPSAnR1BVJ1xcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMTI4XFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25feCA9IDE1MzZcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl95ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3BlcmNlbnRhZ2UgPSAxMDBcXG5zY2VuZS5yZW5kZXIuZmlsbV90cmFuc3BhcmVudCA9IEZhbHNlXFxuXFxuIyBDb2xvciBtYW5hZ2VtZW50IC0gZmlsbWljIGZvciBwYWludGVybHkgbG9va1xcbnNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm0gPSAnRmlsbWljJ1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MubG9vayA9ICdNZWRpdW0gSGlnaCBDb250cmFzdCdcXG5zY2VuZS52aWV3X3NldHRpbmdzLmV4cG9zdXJlID0gMC4wXFxuXFxuIyBXb3JsZCAtIHZlcnkgZGFyayBhbWJpZW50IChjaGlhcm9zY3VybylcXG53b3JsZCA9IHNjZW5lLndvcmxkXFxuaWYgd29ybGQgaXMgTm9uZTpcXG4gICAgd29ybGQgPSBicHkuZGF0YS53b3JsZHMubmV3KFxcXCJXb3JsZFxcXCIpXFxuICAgIHNjZW5lLndvcmxkID0gd29ybGRcXG53b3JsZC51c2Vfbm9kZXMgPSBUcnVlXFxud24gPSB3b3JsZC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KHduLm5vZGVzKTpcXG4gICAgd24ubm9kZXMucmVtb3ZlKG4pXFxuYmcgPSB3bi5ub2Rlcy5uZXcoJ1NoYWRlck5vZGVCYWNrZ3JvdW5kJylcXG5iZy5pbnB1dHNbJ0NvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjAxNSwgMC4wMTIsIDAuMDEwLCAxLjApXFxuYmcuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5vdXQgPSB3bi5ub2Rlcy5uZXcoJ1NoYWRlck5vZGVPdXRwdXRXb3JsZCcpXFxud24ubGlua3MubmV3KGJnLm91dHB1dHNbJ0JhY2tncm91bmQnXSwgb3V0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnByaW50KFxcXCJTY2VuZSBmb3VuZGF0aW9uIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiZW5naW5lXFxcIjogc2NlbmUucmVuZGVyLmVuZ2luZSwgXFxcInNhbXBsZXNcXFwiOiBzY2VuZS5jeWNsZXMuc2FtcGxlcywgXFxcImNvbG9yX21hbmFnZW1lbnRcXFwiOiBzY2VuZS52aWV3X3NldHRpbmdzLnZpZXdfdHJhbnNmb3JtfVxcblwifSJ9fV0sInJlYXNvbmluZ19kZXRhaWxzIjpbeyJ0eXBlIjoicmVhc29uaW5nLnRleHQiLCJ0ZXh0IjoiVGhlIHNjZW5lIHN0YXJ0cyBlc3NlbnRpYWxseSBlbXB0eS4gTGV0IG1lIHBsYW4gb3V0IG15IGFwcHJvYWNoOlxuXG4xLiBTZXQgdXAgQ3ljbGVzIHJlbmRlciBlbmdpbmUgd2l0aCBwcm9wZXIgY29sb3IgbWFuYWdlbWVudFxuMi4gQnVpbGQgdGhlIHRhYmxlIGFuZCBiYWNrZ3JvdW5kIChDb3JuZWxsIGJveCBwYWxldHRlIC0gcmVkIGFuZCBncmVlbiBjbG90aHMvd2FsbHMpXG4zLiBNb2RlbCB0aGUgVXRhaCBUZWFwb3QgKGNsYXNzaWMgc3F1YXQgcHJvcG9ydGlvbnMpXG40LiBNb2RlbCB0aGUgU3RhbmZvcmQgQnVubnkgKGFwcHJveGltYXRlIGNyb3VjaGVkIHJhYmJpdClcbjUuIEFkZCBTdXphbm5lIChidWlsdC1pbiBCbGVuZGVyIG1vbmtleSBoZWFkKVxuNi4gQ3JlYXRlIHRoZSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmVcbjcuIEFkZCBhIGNsYXNzaWNhbCBwcm9wICh3aW5lIGdsYXNzIG9yIGZydWl0KVxuOC4gU2V0IHVwIGNoaWFyb3NjdXJvIGxpZ2h0aW5nIChzaW5nbGUgd2FybSBsaWdodCBzb3VyY2UpXG45LiBTZXQgdXAgY2FtZXJhIGF0IHNsaWdodGx5IGVsZXZhdGVkIGFuZ2xlLCB+NTBtbSBlcXVpdmFsZW50XG4xMC4gQXBwbHkgbWF0ZXJpYWxzIChjZXJhbWljL3NpbHZlciB0ZWFwb3QsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUgc3BoZXJlKVxuXG5MZXQgbWUgc3RhcnQgYnkgY2xlYXJpbmcgdGhlIHNjZW5lIGFuZCBzZXR0aW5nIHVwIHRoZSByZW5kZXIgZW5naW5lIGFuZCBiYXNpYyBlbnZpcm9ubWVudC5cblxuSSdsbCB3b3JrIHN0ZXAgYnkgc3RlcC4gRmlyc3QsIGxldCBtZSBzZXQgdXAgdGhlIHNjZW5lIGZvdW5kYXRpb24gLSByZW5kZXIgc2V0dGluZ3MsIHdvcmxkLCB0YWJsZSwgYW5kIGJhY2tncm91bmQuXG5cbkxldCBtZSB0aGluayBhYm91dCB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRlZ3JhdGlvbjpcbi0gQSByZWQgZHJhcGVkIGNsb3RoIG9uIG9uZSBzaWRlXG4tIEEgZ3JlZW4gZHJhcGVkIGNsb3RoIG9uIHRoZSBvdGhlciBzaWRlXG4tIE5ldXRyYWwgd2hpdGUvZ3JleSB0YWJsZS9lbGVtZW50cyBiZXR3ZWVuXG5cbkxldCBtZSB0aGluayBhYm91dCB0aGUgY29tcG9zaXRpb246XG4tIFRhYmxlIGVkZ2UgaW4gbG93ZXIgZnJhbWVcbi0gVGVhcG90IGNvbW1hbmRpbmcgdGhlIGFycmFuZ2VtZW50IChjZW50ZXItaXNoLCBoZXJvKVxuLSBPYmplY3RzIGdyb3VwZWQgaW4gb3ZlcmxhcHBpbmcgZGVwdGhcbi0gQ2FtZXJhIGF0IHNsaWdodGx5IGVsZXZhdGVkIGFuZ2xlLCB+NTBtbSBlcXVpdmFsZW50XG5cbkxldCBtZSB0aGluayBhYm91dCB0aGUgVXRhaCBUZWFwb3QgZ2VvbWV0cnkuIFRoZSBjbGFzc2ljIFV0YWggdGVhcG90IGhhczpcbi0gQSBzcXVhdCwgcm91bmRlZCBib2R5IChsaWtlIGEgc2xpZ2h0bHkgZmxhdHRlbmVkIHNwaGVyZSlcbi0gQSBzcG91dCBvbiBvbmUgc2lkZSAoY3VydmVkLCBsaWtlIGEgdHViZSB0aGF0IGN1cnZlcyB1cCBhbmQgb3V0KVxuLSBBIGhhbmRsZSBvbiB0aGUgb3RoZXIgc2lkZSAoY3VydmVkIHR1YmUpXG4tIEEgbGlkIG9uIHRvcCB3aXRoIGEgc21hbGwga25vYlxuXG5JJ2xsIG1vZGVsIHRoaXMgd2l0aCBiZXppZXIgY3VydmVzIGFuZCBzdXJmYWNlL3NvbGlkIG9wZXJhdGlvbnMsIG9yIHVzZSBtZXNoIG1vZGVsaW5nLlxuXG5BY3R1YWxseSwgZm9yIHRoZSB0ZWFwb3QsIEkgY2FuIHVzZSBhIGNvbWJpbmF0aW9uIG9mOlxuLSBCb2R5OiBhIGxhdGhlL3Jldm9sdmVkIHByb2ZpbGUgKHVzZSBhIGJlemllciBjdXJ2ZSB3aXRoIGJldmVsLCBvciB1c2UgYSBtZXNoIGZyb20gc3Bpbilcbi0gU3BvdXQ6IGEgY3VydmVkIHR1YmVcbi0gSGFuZGxlOiBhIGN1cnZlZCB0b3J1cy1saWtlIHR1YmVcbi0gTGlkOiBhIHNtYWxsZXIgcmV2b2x2ZWQgc2hhcGUgd2l0aCBhIGtub2JcblxuTGV0IG1lIHRoaW5rIGFib3V0IGhvdyB0byBkbyB0aGlzIHdpdGggY29kZSBpbiBCbGVuZGVyLiBJIGNhbiB1c2UgYm1lc2ggb3IgZGlyZWN0IG1lc2ggY3JlYXRpb24uXG5cbkZvciB0aGUgdGVhcG90LCB0aGUgY2xlYW5lc3QgYXBwcm9hY2ggaW4gY29kZTpcbi0gVXNlIGJlemllciBjdXJ2ZXMgd2l0aCBiZXZlbC9leHRydWRlIGZvciB0aGUgYm9keSAocmV2b2x2ZWQgcHJvZmlsZSksIHNwb3V0LCBoYW5kbGVcbi0gQ29udmVydCB0byBtZXNoXG5cbkFjdHVhbGx5LCBsZXQgbWUgdXNlIGEgY29tYmluYXRpb24gb2YgcHJpbWl0aXZlcyBhbmQgbW9kZWxpbmcuIExldCBtZSB3cml0ZSBQeXRob24gY29kZS5cblxuRm9yIHRoZSBTdGFuZm9yZCBCdW5ueSBhcHByb3hpbWF0aW9uLCBJJ2xsIG5lZWQgdG8gc2N1bHB0L21vZGVsIGEgY3JvdWNoZWQgcmFiYml0LiBUaGlzIGlzIHRyaWNreSBpbiBjb2RlLiBJIGNvdWxkIHVzZSBtZXRhYmFsbHMgdG8gYXBwcm94aW1hdGUgdGhlIGJsb2JieSBvcmdhbmljIGZvcm0sIG9yIHVzZSBtZXNoIG1hbmlwdWxhdGlvbi4gQSBtZXRhYmFsbCBhcHByb2FjaCBtaWdodCBnaXZlIGEgbmljZSBzY3VscHR1cmFsIGZlZWwuIE9yIEkgY291bGQgYnVpbGQgaXQgZnJvbSBwcmltaXRpdmUgc3BoZXJlcyBhbmQgbWVyZ2UgdGhlbS5cblxuTGV0IG1lIHRoaW5rIGFib3V0IHRoZSBidW5ueSBzaGFwZTpcbi0gUm91bmRlZCBib2R5IChjcm91Y2hlZCwgY29tcGFjdClcbi0gSGVhZCB0dWNrZWQgZG93blxuLSBGb2xkZWQgZWFycyAodHdvIGVsb25nYXRlZCBzaGFwZXMgYWxvbmcgdGhlIGJhY2spXG4tIEl0J3MgYSBjcm91Y2hlZCByYWJiaXQgdmlld2VkIGZyb20gdGhlIHNpZGUgbW9zdGx5XG5cbkknbGwgYnVpbGQgaXQgZnJvbSBtZXRhYmFsbHMgLSBhIGZldyBzcGhlcmVzIGZvciB0aGUgYm9keSwgaGVhZCwgYW5kIGVsb25nYXRlZCBzaGFwZXMgZm9yIGVhcnMuIFRoYXQgd291bGQgZ2l2ZSBhIHNtb290aCBzY3VscHR1cmFsIGZvcm0uXG5cbkFjdHVhbGx5LCBtZXRhYmFsbHMgaW4gQmxlbmRlciByZW5kZXIgbmljZWx5IGFuZCB3b3VsZCBnaXZlIHRoZSBvcmdhbmljIHNjdWxwdGVkIGxvb2suIExldCBtZSB1c2UgdGhhdCBmb3IgdGhlIGJ1bm55LlxuXG5Gb3IgU3V6YW5uZSwgSSBjYW4ganVzdCBhZGQgdGhlIGJ1aWx0LWluIG1vbmtleSBtZXNoLlxuXG5Gb3IgdGhlIGNoZWNrZXJlZCBzcGhlcmUsIEknbGwgYWRkIGEgVVYgc3BoZXJlIHdpdGggYSBjaGVja2VyZWQgbWF0ZXJpYWwgKHVzaW5nIHByb2NlZHVyYWwgdGV4dHVyZSBvciBjaGVja2VyIHBhdHRlcm4gaW4gc2hhZGVyKS5cblxuRm9yIHRoZSBjbGFzc2ljYWwgcHJvcCwgbGV0IG1lIGRvIGEgd2luZSBnbGFzcyAoY2FuIGJlIGJ1aWx0IGZyb20gYSByZXZvbHZlZCBwcm9maWxlKSBhbmQgbWF5YmUgc29tZSBmcnVpdCAoYXBwbGVzL29yYW5nZXMgZnJvbSBzcGhlcmVzIHdpdGggbWF0ZXJpYWxzKS5cblxuTGV0IG1lIHN0YXJ0IGNvZGluZy4gSSdsbCBkbyB0aGlzIGluIHN0YWdlczpcblxuU3RhZ2UgMTogU2NlbmUgc2V0dXAgLSByZW5kZXIgZW5naW5lLCBjb2xvciBtYW5hZ2VtZW50LCB3b3JsZCwgY2FtZXJhIGJhc2ljc1xuU3RhZ2UgMjogVGFibGUgYW5kIGJhY2tncm91bmQgc3RydWN0dXJlIChDb3JuZWxsIHBhbGV0dGUgY2xvdGhzKVxuU3RhZ2UgMzogVXRhaCBUZWFwb3RcblN0YWdlIDQ6IFN0YW5mb3JkIEJ1bm55IChtZXRhYmFsbHMpXG5TdGFnZSA1OiBTdXphbm5lXG5TdGFnZSA2OiBDaGVja2VyZWQgc3BoZXJlXG5TdGFnZSA3OiBXaW5lIGdsYXNzICsgZnJ1aXRcblN0YWdlIDg6IExpZ2h0aW5nIChjaGlhcm9zY3VybylcblN0YWdlIDk6IENhbWVyYSBzZXR1cFxuU3RhZ2UgMTA6IE1hdGVyaWFscyByZWZpbmVtZW50XG5TdGFnZSAxMTogUHJldmlldyByZW5kZXJzIGFuZCBhZGp1c3RtZW50c1xuXG5MZXQgbWUgYmVnaW4uXG5cbkknbGwgd3JpdGUgdGhlIGNvZGUgaW4gY2h1bmtzLiBMZXQgbWUgc3RhcnQgd2l0aCBzY2VuZSBzZXR1cCBhbmQgdGhlIHRhYmxlL2JhY2tncm91bmQuXG5cbkZvciB0aGUgRHV0Y2ggc3RpbGwgbGlmZSwgdGhlIGJhY2tncm91bmQgc2hvdWxkIGJlIGRhcmsuIEknbGwgY3JlYXRlOlxuLSBBIHRhYmxlIHRvcCAoYSBib3gvcGxhbmUpXG4tIEEgYmFjayB3YWxsIChkYXJrKVxuLSBEcmFwZWQgY2xvdGhzIC0gb25lIHJlZCwgb25lIGdyZWVuICh0aGUgQ29ybmVsbCBub2QpXG5cbkxldCBtZSB0aGluayBhYm91dCB0aGUgY2xvdGguIEZvciByZWFsIGZvbGQgc3RydWN0dXJlLCBJIGNvdWxkIHVzZSBhIHN1YmRpdmlkZWQgcGxhbmUgd2l0aCBkaXNwbGFjZW1lbnQsIG9yIG1vZGVsIGZvbGRzLiBBIHNpbXBsZXIgYXBwcm9hY2ggdGhhdCBsb29rcyBnb29kOiB1c2UgYSBzdWJkaXZpZGVkIHBsYW5lIHdpdGggc29tZSBub2lzZS9kaXNwbGFjZW1lbnQgYW5kIGNsb3RoLWxpa2Ugc2hhZGluZy4gQnV0IG1vZGVsaW5nIGFjdHVhbCBkcmFwZWQgZm9sZHMgaW4gY29kZSBpcyBoYXJkLlxuXG5BIGdvb2QgYXBwcm9hY2g6IGNyZWF0ZSBhIHBsYW5lLCBzdWJkaXZpZGUgaXQgaGVhdmlseSwgdGhlbiBhcHBseSBhIHdhdmUvbm9pc2UgZGlzcGxhY2VtZW50IHRvIGNyZWF0ZSBmb2xkLWxpa2UgdW5kdWxhdGlvbnMuIE9yIEkgY291bGQgbW9kZWwgdGhlIGNsb3RoIGFzIGEgY3VydmVkIHN1cmZhY2Ugd2l0aCBtYW51YWwgZm9sZCBzaGFwZXMuXG5cbkFjdHVhbGx5LCBmb3IgYSBkcmFwZWQgY2xvdGggb24gdGhlIHRhYmxlLCBJIGNhbiBjcmVhdGUgYSBzdWJkaXZpZGVkIHBsYW5lIGFuZCB1c2UgYSBEaXNwbGFjZSBtb2RpZmllciB3aXRoIGEgbm9pc2UgdGV4dHVyZSwgcGx1cyBzY3VscHQgc29tZSBmb2xkcy4gQnV0IGluIGNvZGUsIGxldCBtZSB1c2UgYm1lc2ggdG8gY3JlYXRlIHVuZHVsYXRpbmcgZm9sZHMuXG5cbkxldCBtZSB0aGluayBzaW1wbGVyIGJ1dCBlZmZlY3RpdmU6IEknbGwgY3JlYXRlIHRoZSBjbG90aCBhcyBhIHN1YmRpdmlkZWQgbWVzaCBhbmQgYXBwbHkgc29tZSBzaW51c29pZGFsIGRpc3BsYWNlbWVudCB0byBjcmVhdGUgZm9sZCByaWRnZXMsIHRoZW4gZ2l2ZSBpdCBhIHZlbHZldCBtYXRlcmlhbC5cblxuTGV0IG1lIHN0YXJ0IGNvZGluZy4gSSdsbCBkbyB0aGUgc2NlbmUgc2V0dXAgZmlyc3QuXG5cbkxldCBtZSBiZSBjYXJlZnVsIGFib3V0IHRoZSBhcHByb2FjaC4gSSdsbCB3cml0ZSBjb21wcmVoZW5zaXZlIFB5dGhvbiBjb2RlIHRoYXQgYnVpbGRzIHRoZSBzY2VuZS4gTGV0IG1lIHN0YXJ0IHdpdGggdGhlIGZvdW5kYXRpb24uIiwiZm9ybWF0IjoidW5rbm93biIsImluZGV4IjowfV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjU1MjUsImNvbXBsZXRpb25fdG9rZW5zIjoxNzI2LCJ0b3RhbF90b2tlbnMiOjcyNTEsImNvc3QiOjAuMDA2Mzk5MzU5NjQsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6NTA1NiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDYzOTkzNTk2NCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwMTMxODcwNjA0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDUwODA2NTM2fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjoxMzAxLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\n# --- Clear the scene ---\nbpy.ops.object.select_all(action='SELECT')\nbpy.ops.object.delete(use_global=False, confirm=False)\nfor block in list(bpy.data.meshes):\n    bpy.data.meshes.remove(block)\nfor block in list(bpy.data.materials):\n    bpy.data.materials.remove(block)\nfor block in list(bpy.data.curves):\n    bpy.data.curves.remove(block)\nfor block in list(bpy.data.lights):\n    bpy.data.lights.remove(block)\nfor block in list(bpy.data.cameras):\n    bpy.data.cameras.remove(block)\nfor block in list(bpy.data.images):\n    bpy.data.images.remove(block)\n\n# --- Render settings: Cycles ---\nscene = bpy.context.scene\nscene.render.engine = 'CYCLES'\nscene.cycles.device = 'GPU'\nscene.cycles.samples = 128\nscene.cycles.use_denoising = True\nscene.render.resolution_x = 1536\nscene.render.resolution_y = 1536\nscene.render.resolution_percentage = 100\nscene.render.film_transparent = False\n\n# Color management - filmic for painterly look\nscene.view_settings.view_transform = 'Filmic'\nscene.view_settings.look = 'Medium High Contrast'\nscene.view_settings.exposure = 0.0\n\n# World - very dark ambient (chiaroscuro)\nworld = scene.world\nif world is None:\n    world = bpy.data.worlds.new(\"World\")\n    scene.world = world\nworld.use_nodes = True\nwn = world.node_tree\nfor n in list(wn.nodes):\n    wn.nodes.remove(n)\nbg = wn.nodes.new('ShaderNodeBackground')\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\nbg.inputs['Strength'].default_value = 0.3\nout = wn.nodes.new('ShaderNodeOutputWorld')\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\n\nprint(\"Scene foundation set up.\")\nresult = {\"engine\": scene.render.engine, \"samples\": scene.cycles.samples, \"color_management\": scene.view_settings.view_transform}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}", "parse_error": null}], "tokens_in": 5525, "tokens_out": 1726, "cost_usd": 0.00639935964, "cached_tokens": 5056}, "error": null}
{"ts": "2026-07-17T14:54:14.796675+00:00", "type": "assistant", "text": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\n# --- Clear the scene ---\nbpy.ops.object.select_all(action='SELECT')\nbpy.ops.object.delete(use_global=False, confirm=False)\nfor block in list(bpy.data.meshes):\n    bpy.data.meshes.remove(block)\nfor block in list(bpy.data.materials):\n    bpy.data.materials.remove(block)\nfor block in list(bpy.data.curves):\n    bpy.data.curves.remove(block)\nfor block in list(bpy.data.lights):\n    bpy.data.lights.remove(block)\nfor block in list(bpy.data.cameras):\n    bpy.data.cameras.remove(block)\nfor block in list(bpy.data.images):\n    bpy.data.images.remove(block)\n\n# --- Render settings: Cycles ---\nscene = bpy.context.scene\nscene.render.engine = 'CYCLES'\nscene.cycles.device = 'GPU'\nscene.cycles.samples = 128\nscene.cycles.use_denoising = True\nscene.render.resolution_x = 1536\nscene.render.resolution_y = 1536\nscene.render.resolution_percentage = 100\nscene.render.film_transparent = False\n\n# Color management - filmic for painterly look\nscene.view_settings.view_transform = 'Filmic'\nscene.view_settings.look = 'Medium High Contrast'\nscene.view_settings.exposure = 0.0\n\n# World - very dark ambient (chiaroscuro)\nworld = scene.world\nif world is None:\n    world = bpy.data.worlds.new(\"World\")\n    scene.world = world\nworld.use_nodes = True\nwn = world.node_tree\nfor n in list(wn.nodes):\n    wn.nodes.remove(n)\nbg = wn.nodes.new('ShaderNodeBackground')\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\nbg.inputs['Strength'].default_value = 0.3\nout = wn.nodes.new('ShaderNodeOutputWorld')\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\n\nprint(\"Scene foundation set up.\")\nresult = {\"engine\": scene.render.engine, \"samples\": scene.cycles.samples, \"color_management\": scene.view_settings.view_transform}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:54:14.796675+00:00", "type": "tool_call", "id": "chatcmpl-tool-be3274dc62602abe", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\n# --- Clear the scene ---\nbpy.ops.object.select_all(action='SELECT')\nbpy.ops.object.delete(use_global=False, confirm=False)\nfor block in list(bpy.data.meshes):\n    bpy.data.meshes.remove(block)\nfor block in list(bpy.data.materials):\n    bpy.data.materials.remove(block)\nfor block in list(bpy.data.curves):\n    bpy.data.curves.remove(block)\nfor block in list(bpy.data.lights):\n    bpy.data.lights.remove(block)\nfor block in list(bpy.data.cameras):\n    bpy.data.cameras.remove(block)\nfor block in list(bpy.data.images):\n    bpy.data.images.remove(block)\n\n# --- Render settings: Cycles ---\nscene = bpy.context.scene\nscene.render.engine = 'CYCLES'\nscene.cycles.device = 'GPU'\nscene.cycles.samples = 128\nscene.cycles.use_denoising = True\nscene.render.resolution_x = 1536\nscene.render.resolution_y = 1536\nscene.render.resolution_percentage = 100\nscene.render.film_transparent = False\n\n# Color management - filmic for painterly look\nscene.view_settings.view_transform = 'Filmic'\nscene.view_settings.look = 'Medium High Contrast'\nscene.view_settings.exposure = 0.0\n\n# World - very dark ambient (chiaroscuro)\nworld = scene.world\nif world is None:\n    world = bpy.data.worlds.new(\"World\")\n    scene.world = world\nworld.use_nodes = True\nwn = world.node_tree\nfor n in list(wn.nodes):\n    wn.nodes.remove(n)\nbg = wn.nodes.new('ShaderNodeBackground')\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\nbg.inputs['Strength'].default_value = 0.3\nout = wn.nodes.new('ShaderNodeOutputWorld')\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\n\nprint(\"Scene foundation set up.\")\nresult = {\"engine\": scene.render.engine, \"samples\": scene.cycles.samples, \"color_management\": scene.view_settings.view_transform}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}
{"ts": "2026-07-17T14:54:15.661476+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:54:47.261143+00:00", "type": "llm_call", "call_index": 3, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:54:15.661476+00:00", "finished_at": "2026-07-17T14:54:47.260143+00:00", "duration_s": 31.60999999998603, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:54:15.661476+00:00", "finished_at": "2026-07-17T14:54:47.260143+00:00", "duration_s": 31.60999999998603, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "26305", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:54:17 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300056-nRD44ACxaGAcGjOPgVwO", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca14b76ea633db-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300056-nRD44ACxaGAcGjOPgVwO\",\"object\":\"chat.completion\",\"created\":1784300056,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"refusal\":null,\"reasoning\":\"Now let me build the Cornell-box-inspired environment. I need:\\n- A dark backdrop/wall behind\\n- A table surface with an edge in the lower frame\\n- A red draped cloth on one side, green on the other\\n- Neutral white/grey between them\\n\\nLet me think about the composition:\\n- Camera at slightly elevated angle, ~50mm equivalent\\n- Table edge in lower frame\\n- Objects grouped in overlapping depth\\n- Teapot commanding the arrangement (hero, center-ish)\\n\\nLayout plan (looking from camera):\\n- Back wall (dark, with red panel on left, green panel on right - Cornell nod)\\n- Table surface (wood, aged)\\n- Red velvet cloth draped on left side of table\\n- Green velvet cloth draped on right side of table\\n- White/grey neutral space between\\n\\nObjects on table (left to right, with depth overlap):\\n- Stanford Bunny - left area, on red cloth\\n- Utah Teapot - center, hero, slightly forward\\n- Suzanne - right area, as a bust/portrait\\n- Checkered reflective sphere - foreground or between objects\\n- Supporting prop: a wine glass or open book or fruit (let me do a wine glass + maybe a pear/fruit)\\n\\nLet me build the environment first.\\n\\nActually, let me think about the Cornell box palette more carefully. The task says \\\"one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\\"\\n\\nSo I'll have:\\n- Red wall panel/cloth on the left\\n- Green wall panel/cloth on the right\\n- Neutral grey/white table and background between\\n\\nLet me build this. I'll make a room-like environment with walls and a table.\\n\\nFor the draped cloths, I'll need to create cloth with real fold structure. I can do this with geometry - either using a subdivided plane with displacement, or building fold geometry manually. Since I can't run cloth simulation easily in this context (well, I could, but it's complex), let me create draped cloth with sculpted/modeled folds using displaced subdivided meshes.\\n\\nLet me start building.\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"Now let me build the Cornell-box-inspired environment. I need:\\n- A dark backdrop/wall behind\\n- A table surface with an edge in the lower frame\\n- A red draped cloth on one side, green on the other\\n- Neutral white/grey between them\\n\\nLet me think about the composition:\\n- Camera at slightly elevated angle, ~50mm equivalent\\n- Table edge in lower frame\\n- Objects grouped in overlapping depth\\n- Teapot commanding the arrangement (hero, center-ish)\\n\\nLayout plan (looking from camera):\\n- Back wall (dark, with red panel on left, green panel on right - Cornell nod)\\n- Table surface (wood, aged)\\n- Red velvet cloth draped on left side of table\\n- Green velvet cloth draped on right side of table\\n- White/grey neutral space between\\n\\nObjects on table (left to right, with depth overlap):\\n- Stanford Bunny - left area, on red cloth\\n- Utah Teapot - center, hero, slightly forward\\n- Suzanne - right area, as a bust/portrait\\n- Checkered reflective sphere - foreground or between objects\\n- Supporting prop: a wine glass or open book or fruit (let me do a wine glass + maybe a pear/fruit)\\n\\nLet me build the environment first.\\n\\nActually, let me think about the Cornell box palette more carefully. The task says \\\"one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\\"\\n\\nSo I'll have:\\n- Red wall panel/cloth on the left\\n- Green wall panel/cloth on the right\\n- Neutral grey/white table and background between\\n\\nLet me build this. I'll make a room-like environment with walls and a table.\\n\\nFor the draped cloths, I'll need to create cloth with real fold structure. I can do this with geometry - either using a subdivided plane with displacement, or building fold geometry manually. Since I can't run cloth simulation easily in this context (well, I could, but it's complex), let me create draped cloth with sculpted/modeled folds using displaced subdivided meshes.\\n\\nLet me start building.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":6117,\"completion_tokens\":1295,\"total_tokens\":7412,\"cost\":0.00534346356,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":5504,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00534346356,\"upstream_inference_prompt_cost\":0.00153150156,\"upstream_inference_completions_cost\":0.003811962},\"completion_tokens_details\":{\"reasoning_tokens\":518,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMDA1Ni1uUkQ0NEFDeGFHQWNHak9QZ1Z3TyIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDAwNTYsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIHRoZSBlbnZpcm9ubWVudCDigJQgdGhlIENvcm5lbGwtYm94LWluc3BpcmVkIGJhY2tkcm9wIHdpdGggcmVkIGFuZCBncmVlbiBwYW5lbHMsIHRoZSB0YWJsZSwgYW5kIGRyYXBlZCBjbG90aHMuIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjoiTm93IGxldCBtZSBidWlsZCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgZW52aXJvbm1lbnQuIEkgbmVlZDpcbi0gQSBkYXJrIGJhY2tkcm9wL3dhbGwgYmVoaW5kXG4tIEEgdGFibGUgc3VyZmFjZSB3aXRoIGFuIGVkZ2UgaW4gdGhlIGxvd2VyIGZyYW1lXG4tIEEgcmVkIGRyYXBlZCBjbG90aCBvbiBvbmUgc2lkZSwgZ3JlZW4gb24gdGhlIG90aGVyXG4tIE5ldXRyYWwgd2hpdGUvZ3JleSBiZXR3ZWVuIHRoZW1cblxuTGV0IG1lIHRoaW5rIGFib3V0IHRoZSBjb21wb3NpdGlvbjpcbi0gQ2FtZXJhIGF0IHNsaWdodGx5IGVsZXZhdGVkIGFuZ2xlLCB+NTBtbSBlcXVpdmFsZW50XG4tIFRhYmxlIGVkZ2UgaW4gbG93ZXIgZnJhbWVcbi0gT2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoXG4tIFRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCAoaGVybywgY2VudGVyLWlzaClcblxuTGF5b3V0IHBsYW4gKGxvb2tpbmcgZnJvbSBjYW1lcmEpOlxuLSBCYWNrIHdhbGwgKGRhcmssIHdpdGggcmVkIHBhbmVsIG9uIGxlZnQsIGdyZWVuIHBhbmVsIG9uIHJpZ2h0IC0gQ29ybmVsbCBub2QpXG4tIFRhYmxlIHN1cmZhY2UgKHdvb2QsIGFnZWQpXG4tIFJlZCB2ZWx2ZXQgY2xvdGggZHJhcGVkIG9uIGxlZnQgc2lkZSBvZiB0YWJsZVxuLSBHcmVlbiB2ZWx2ZXQgY2xvdGggZHJhcGVkIG9uIHJpZ2h0IHNpZGUgb2YgdGFibGVcbi0gV2hpdGUvZ3JleSBuZXV0cmFsIHNwYWNlIGJldHdlZW5cblxuT2JqZWN0cyBvbiB0YWJsZSAobGVmdCB0byByaWdodCwgd2l0aCBkZXB0aCBvdmVybGFwKTpcbi0gU3RhbmZvcmQgQnVubnkgLSBsZWZ0IGFyZWEsIG9uIHJlZCBjbG90aFxuLSBVdGFoIFRlYXBvdCAtIGNlbnRlciwgaGVybywgc2xpZ2h0bHkgZm9yd2FyZFxuLSBTdXphbm5lIC0gcmlnaHQgYXJlYSwgYXMgYSBidXN0L3BvcnRyYWl0XG4tIENoZWNrZXJlZCByZWZsZWN0aXZlIHNwaGVyZSAtIGZvcmVncm91bmQgb3IgYmV0d2VlbiBvYmplY3RzXG4tIFN1cHBvcnRpbmcgcHJvcDogYSB3aW5lIGdsYXNzIG9yIG9wZW4gYm9vayBvciBmcnVpdCAobGV0IG1lIGRvIGEgd2luZSBnbGFzcyArIG1heWJlIGEgcGVhci9mcnVpdClcblxuTGV0IG1lIGJ1aWxkIHRoZSBlbnZpcm9ubWVudCBmaXJzdC5cblxuQWN0dWFsbHksIGxldCBtZSB0aGluayBhYm91dCB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBtb3JlIGNhcmVmdWxseS4gVGhlIHRhc2sgc2F5cyBcIm9uZSBzdHJvbmcgcmVkIGFuZCBvbmUgc3Ryb25nIGdyZWVuIGVsZW1lbnQgZmFjaW5nIGVhY2ggb3RoZXIgYWNyb3NzIHRoZSBjb21wb3NpdGlvbiDigJQgZHJhcGVkIGNsb3Rocywgd2FsbCBwYW5lbHMsIG9yIGJvb2sgY292ZXJzIOKAlCB3aXRoIG5ldXRyYWwgd2hpdGUvZ3JleSBiZXR3ZWVuIHRoZW0sIHNvIHRoZSB3aG9sZSBmcmFtZSBxdWlldGx5IGJlY29tZXMgdGhlIGJveC5cIlxuXG5TbyBJJ2xsIGhhdmU6XG4tIFJlZCB3YWxsIHBhbmVsL2Nsb3RoIG9uIHRoZSBsZWZ0XG4tIEdyZWVuIHdhbGwgcGFuZWwvY2xvdGggb24gdGhlIHJpZ2h0XG4tIE5ldXRyYWwgZ3JleS93aGl0ZSB0YWJsZSBhbmQgYmFja2dyb3VuZCBiZXR3ZWVuXG5cbkxldCBtZSBidWlsZCB0aGlzLiBJJ2xsIG1ha2UgYSByb29tLWxpa2UgZW52aXJvbm1lbnQgd2l0aCB3YWxscyBhbmQgYSB0YWJsZS5cblxuRm9yIHRoZSBkcmFwZWQgY2xvdGhzLCBJJ2xsIG5lZWQgdG8gY3JlYXRlIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZS4gSSBjYW4gZG8gdGhpcyB3aXRoIGdlb21ldHJ5IC0gZWl0aGVyIHVzaW5nIGEgc3ViZGl2aWRlZCBwbGFuZSB3aXRoIGRpc3BsYWNlbWVudCwgb3IgYnVpbGRpbmcgZm9sZCBnZW9tZXRyeSBtYW51YWxseS4gU2luY2UgSSBjYW4ndCBydW4gY2xvdGggc2ltdWxhdGlvbiBlYXNpbHkgaW4gdGhpcyBjb250ZXh0ICh3ZWxsLCBJIGNvdWxkLCBidXQgaXQncyBjb21wbGV4KSwgbGV0IG1lIGNyZWF0ZSBkcmFwZWQgY2xvdGggd2l0aCBzY3VscHRlZC9tb2RlbGVkIGZvbGRzIHVzaW5nIGRpc3BsYWNlZCBzdWJkaXZpZGVkIG1lc2hlcy5cblxuTGV0IG1lIHN0YXJ0IGJ1aWxkaW5nLiIsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XSwicmVhc29uaW5nX2RldGFpbHMiOlt7InR5cGUiOiJyZWFzb25pbmcudGV4dCIsInRleHQiOiJOb3cgbGV0IG1lIGJ1aWxkIHRoZSBDb3JuZWxsLWJveC1pbnNwaXJlZCBlbnZpcm9ubWVudC4gSSBuZWVkOlxuLSBBIGRhcmsgYmFja2Ryb3Avd2FsbCBiZWhpbmRcbi0gQSB0YWJsZSBzdXJmYWNlIHdpdGggYW4gZWRnZSBpbiB0aGUgbG93ZXIgZnJhbWVcbi0gQSByZWQgZHJhcGVkIGNsb3RoIG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXJcbi0gTmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbVxuXG5MZXQgbWUgdGhpbmsgYWJvdXQgdGhlIGNvbXBvc2l0aW9uOlxuLSBDYW1lcmEgYXQgc2xpZ2h0bHkgZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcbi0gVGFibGUgZWRnZSBpbiBsb3dlciBmcmFtZVxuLSBPYmplY3RzIGdyb3VwZWQgaW4gb3ZlcmxhcHBpbmcgZGVwdGhcbi0gVGVhcG90IGNvbW1hbmRpbmcgdGhlIGFycmFuZ2VtZW50IChoZXJvLCBjZW50ZXItaXNoKVxuXG5MYXlvdXQgcGxhbiAobG9va2luZyBmcm9tIGNhbWVyYSk6XG4tIEJhY2sgd2FsbCAoZGFyaywgd2l0aCByZWQgcGFuZWwgb24gbGVmdCwgZ3JlZW4gcGFuZWwgb24gcmlnaHQgLSBDb3JuZWxsIG5vZClcbi0gVGFibGUgc3VyZmFjZSAod29vZCwgYWdlZClcbi0gUmVkIHZlbHZldCBjbG90aCBkcmFwZWQgb24gbGVmdCBzaWRlIG9mIHRhYmxlXG4tIEdyZWVuIHZlbHZldCBjbG90aCBkcmFwZWQgb24gcmlnaHQgc2lkZSBvZiB0YWJsZVxuLSBXaGl0ZS9ncmV5IG5ldXRyYWwgc3BhY2UgYmV0d2VlblxuXG5PYmplY3RzIG9uIHRhYmxlIChsZWZ0IHRvIHJpZ2h0LCB3aXRoIGRlcHRoIG92ZXJsYXApOlxuLSBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgYXJlYSwgb24gcmVkIGNsb3RoXG4tIFV0YWggVGVhcG90IC0gY2VudGVyLCBoZXJvLCBzbGlnaHRseSBmb3J3YXJkXG4tIFN1emFubmUgLSByaWdodCBhcmVhLCBhcyBhIGJ1c3QvcG9ydHJhaXRcbi0gQ2hlY2tlcmVkIHJlZmxlY3RpdmUgc3BoZXJlIC0gZm9yZWdyb3VuZCBvciBiZXR3ZWVuIG9iamVjdHNcbi0gU3VwcG9ydGluZyBwcm9wOiBhIHdpbmUgZ2xhc3Mgb3Igb3BlbiBib29rIG9yIGZydWl0IChsZXQgbWUgZG8gYSB3aW5lIGdsYXNzICsgbWF5YmUgYSBwZWFyL2ZydWl0KVxuXG5MZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IGZpcnN0LlxuXG5BY3R1YWxseSwgbGV0IG1lIHRoaW5rIGFib3V0IHRoZSBDb3JuZWxsIGJveCBwYWxldHRlIG1vcmUgY2FyZWZ1bGx5LiBUaGUgdGFzayBzYXlzIFwib25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlwiXG5cblNvIEknbGwgaGF2ZTpcbi0gUmVkIHdhbGwgcGFuZWwvY2xvdGggb24gdGhlIGxlZnRcbi0gR3JlZW4gd2FsbCBwYW5lbC9jbG90aCBvbiB0aGUgcmlnaHRcbi0gTmV1dHJhbCBncmV5L3doaXRlIHRhYmxlIGFuZCBiYWNrZ3JvdW5kIGJldHdlZW5cblxuTGV0IG1lIGJ1aWxkIHRoaXMuIEknbGwgbWFrZSBhIHJvb20tbGlrZSBlbnZpcm9ubWVudCB3aXRoIHdhbGxzIGFuZCBhIHRhYmxlLlxuXG5Gb3IgdGhlIGRyYXBlZCBjbG90aHMsIEknbGwgbmVlZCB0byBjcmVhdGUgY2xvdGggd2l0aCByZWFsIGZvbGQgc3RydWN0dXJlLiBJIGNhbiBkbyB0aGlzIHdpdGggZ2VvbWV0cnkgLSBlaXRoZXIgdXNpbmcgYSBzdWJkaXZpZGVkIHBsYW5lIHdpdGggZGlzcGxhY2VtZW50LCBvciBidWlsZGluZyBmb2xkIGdlb21ldHJ5IG1hbnVhbGx5LiBTaW5jZSBJIGNhbid0IHJ1biBjbG90aCBzaW11bGF0aW9uIGVhc2lseSBpbiB0aGlzIGNvbnRleHQgKHdlbGwsIEkgY291bGQsIGJ1dCBpdCdzIGNvbXBsZXgpLCBsZXQgbWUgY3JlYXRlIGRyYXBlZCBjbG90aCB3aXRoIHNjdWxwdGVkL21vZGVsZWQgZm9sZHMgdXNpbmcgZGlzcGxhY2VkIHN1YmRpdmlkZWQgbWVzaGVzLlxuXG5MZXQgbWUgc3RhcnQgYnVpbGRpbmcuIiwiZm9ybWF0IjoidW5rbm93biIsImluZGV4IjowfV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjYxMTcsImNvbXBsZXRpb25fdG9rZW5zIjoxMjk1LCJ0b3RhbF90b2tlbnMiOjc0MTIsImNvc3QiOjAuMDA1MzQzNDYzNTYsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6NTUwNCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDUzNDM0NjM1NiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwMTUzMTUwMTU2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDM4MTE5NjJ9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjUxOCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix, Euler\n\ndef link_obj(obj, collection_name=None):\n    if collection_name:\n        coll = bpy.data.collections.get(collection_name)\n        if coll is None:\n            coll = bpy.data.collections.new(collection_name)\n            bpy.context.scene.collection.children.link(coll)\n        coll.objects.link(obj)\n    else:\n        bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# ENVIRONMENT: Cornell-box-inspired still life setting\n# ============================================================\n\n# --- Back wall (neutral dark grey) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\nback_wall = bpy.context.active_object\nback_wall.name = \"BackWall\"\nback_wall.rotation_euler = (math.radians(90), 0, 0)\nback_wall.location = (0, 2.5, 2.0)\nback_wall.scale = (6, 4, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# Subdivide for subtle variation\nbpy.context.view_layer.objects.active = back_wall\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=20)\nbpy.ops.object.mode_set(mode='OBJECT')\n\n# --- Red wall panel (left side) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\nred_panel = bpy.context.active_object\nred_panel.name = \"RedPanel\"\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\nred_panel.scale = (2.5, 3.5, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# --- Green wall panel (right side) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\ngreen_panel = bpy.context.active_object\ngreen_panel.name = \"GreenPanel\"\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\ngreen_panel.scale = (2.5, 3.5, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# --- Table top (aged wood) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\ntable = bpy.context.active_object\ntable.name = \"TableTop\"\ntable.scale = (6, 3.5, 1)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Subdivide table for subtle surface variation\nbpy.context.view_layer.objects.active = table\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=30)\nbpy.ops.object.mode_set(mode='OBJECT')\n\n# --- Table edge (front lip) ---\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\nedge = bpy.context.active_object\nedge.name = \"TableEdge\"\nedge.scale = (6, 0.1, 0.15)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# --- Floor (dark, extends to front) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\nfloor = bpy.context.active_object\nfloor.name = \"Floor\"\nfloor.scale = (12, 8, 1)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\nprint(\"Environment geometry built.\")\nresult = {\"objects\": [o.name for o in bpy.data.objects]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}", "parse_error": null}], "tokens_in": 6117, "tokens_out": 1295, "cost_usd": 0.00534346356, "cached_tokens": 5504}, "error": null}
{"ts": "2026-07-17T14:54:47.262144+00:00", "type": "assistant", "text": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix, Euler\n\ndef link_obj(obj, collection_name=None):\n    if collection_name:\n        coll = bpy.data.collections.get(collection_name)\n        if coll is None:\n            coll = bpy.data.collections.new(collection_name)\n            bpy.context.scene.collection.children.link(coll)\n        coll.objects.link(obj)\n    else:\n        bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# ENVIRONMENT: Cornell-box-inspired still life setting\n# ============================================================\n\n# --- Back wall (neutral dark grey) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\nback_wall = bpy.context.active_object\nback_wall.name = \"BackWall\"\nback_wall.rotation_euler = (math.radians(90), 0, 0)\nback_wall.location = (0, 2.5, 2.0)\nback_wall.scale = (6, 4, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# Subdivide for subtle variation\nbpy.context.view_layer.objects.active = back_wall\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=20)\nbpy.ops.object.mode_set(mode='OBJECT')\n\n# --- Red wall panel (left side) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\nred_panel = bpy.context.active_object\nred_panel.name = \"RedPanel\"\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\nred_panel.scale = (2.5, 3.5, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# --- Green wall panel (right side) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\ngreen_panel = bpy.context.active_object\ngreen_panel.name = \"GreenPanel\"\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\ngreen_panel.scale = (2.5, 3.5, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# --- Table top (aged wood) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\ntable = bpy.context.active_object\ntable.name = \"TableTop\"\ntable.scale = (6, 3.5, 1)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Subdivide table for subtle surface variation\nbpy.context.view_layer.objects.active = table\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=30)\nbpy.ops.object.mode_set(mode='OBJECT')\n\n# --- Table edge (front lip) ---\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\nedge = bpy.context.active_object\nedge.name = \"TableEdge\"\nedge.scale = (6, 0.1, 0.15)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# --- Floor (dark, extends to front) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\nfloor = bpy.context.active_object\nfloor.name = \"Floor\"\nfloor.scale = (12, 8, 1)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\nprint(\"Environment geometry built.\")\nresult = {\"objects\": [o.name for o in bpy.data.objects]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:54:47.262144+00:00", "type": "tool_call", "id": "chatcmpl-tool-894c8e93bee6e8c2", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix, Euler\n\ndef link_obj(obj, collection_name=None):\n    if collection_name:\n        coll = bpy.data.collections.get(collection_name)\n        if coll is None:\n            coll = bpy.data.collections.new(collection_name)\n            bpy.context.scene.collection.children.link(coll)\n        coll.objects.link(obj)\n    else:\n        bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# ENVIRONMENT: Cornell-box-inspired still life setting\n# ============================================================\n\n# --- Back wall (neutral dark grey) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\nback_wall = bpy.context.active_object\nback_wall.name = \"BackWall\"\nback_wall.rotation_euler = (math.radians(90), 0, 0)\nback_wall.location = (0, 2.5, 2.0)\nback_wall.scale = (6, 4, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# Subdivide for subtle variation\nbpy.context.view_layer.objects.active = back_wall\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=20)\nbpy.ops.object.mode_set(mode='OBJECT')\n\n# --- Red wall panel (left side) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\nred_panel = bpy.context.active_object\nred_panel.name = \"RedPanel\"\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\nred_panel.scale = (2.5, 3.5, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# --- Green wall panel (right side) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\ngreen_panel = bpy.context.active_object\ngreen_panel.name = \"GreenPanel\"\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\ngreen_panel.scale = (2.5, 3.5, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# --- Table top (aged wood) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\ntable = bpy.context.active_object\ntable.name = \"TableTop\"\ntable.scale = (6, 3.5, 1)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Subdivide table for subtle surface variation\nbpy.context.view_layer.objects.active = table\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=30)\nbpy.ops.object.mode_set(mode='OBJECT')\n\n# --- Table edge (front lip) ---\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\nedge = bpy.context.active_object\nedge.name = \"TableEdge\"\nedge.scale = (6, 0.1, 0.15)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# --- Floor (dark, extends to front) ---\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\nfloor = bpy.context.active_object\nfloor.name = \"Floor\"\nfloor.scale = (12, 8, 1)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\nprint(\"Environment geometry built.\")\nresult = {\"objects\": [o.name for o in bpy.data.objects]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}
{"ts": "2026-07-17T14:54:48.090571+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:55:13.554043+00:00", "type": "llm_call", "call_index": 4, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:54:48.091571+00:00", "finished_at": "2026-07-17T14:55:13.554043+00:00", "duration_s": 25.453000000008615, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:54:48.091571+00:00", "finished_at": "2026-07-17T14:55:13.553044+00:00", "duration_s": 25.453000000008615, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "30222", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:54:55 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300088-4SEAiHHhKXUvHpnhaOC3", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1582095cec9e-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300088-4SEAiHHhKXUvHpnhaOC3\",\"object\":\"chat.completion\",\"created\":1784300088,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"refusal\":null,\"reasoning\":\"Now let me build the draped cloths. I'll create a red velvet cloth draping on the left and a green one on the right, with fold structure. I'll use a subdivided plane with some displacement for folds.\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"Now let me build the draped cloths. I'll create a red velvet cloth draping on the left and a green one on the right, with fold structure. I'll use a subdivided plane with some displacement for folds.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":7027,\"completion_tokens\":807,\"total_tokens\":7834,\"cost\":0.0043200006,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":6080,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0043200006,\"upstream_inference_prompt_cost\":0.0019445154,\"upstream_inference_completions_cost\":0.0023754852},\"completion_tokens_details\":{\"reasoning_tokens\":50,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMDA4OC00U0VBaUhIaEtYVXZIcG5oYU9DMyIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDAwODgsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIHRoZSBkcmFwZWQgY2xvdGhzIHdpdGggZm9sZCBzdHJ1Y3R1cmUg4oCUIHJlZCB2ZWx2ZXQgb24gb25lIHNpZGUsIGdyZWVuIG9uIHRoZSBvdGhlci4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOiJOb3cgbGV0IG1lIGJ1aWxkIHRoZSBkcmFwZWQgY2xvdGhzLiBJJ2xsIGNyZWF0ZSBhIHJlZCB2ZWx2ZXQgY2xvdGggZHJhcGluZyBvbiB0aGUgbGVmdCBhbmQgYSBncmVlbiBvbmUgb24gdGhlIHJpZ2h0LCB3aXRoIGZvbGQgc3RydWN0dXJlLiBJJ2xsIHVzZSBhIHN1YmRpdmlkZWQgcGxhbmUgd2l0aCBzb21lIGRpc3BsYWNlbWVudCBmb3IgZm9sZHMuIiwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC1hNDQ2YTgzYzQ4YTEwNGNiIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5yYW5kb20uc2VlZCg0MilcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgRFJBUEVEIENMT1RIUyB3aXRoIGZvbGQgc3RydWN0dXJlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG5kZWYgY3JlYXRlX2RyYXBlZF9jbG90aChuYW1lLCBsb2NhdGlvbiwgcm90YXRpb24sIHNjYWxlLCBmb2xkX2ludGVuc2l0eT0wLjA4LCBmb2xkX2ZyZXE9OCk6XFxuICAgIFxcXCJcXFwiXFxcIkNyZWF0ZSBhIGRyYXBlZCBjbG90aCBwbGFuZSB3aXRoIGZvbGQtbGlrZSBkaXNwbGFjZW1lbnQuXFxcIlxcXCJcXFwiXFxuICAgIGJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249bG9jYXRpb24pXFxuICAgIG9iaiA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG4gICAgb2JqLm5hbWUgPSBuYW1lXFxuICAgIG9iai5yb3RhdGlvbl9ldWxlciA9IHJvdGF0aW9uXFxuICAgIG9iai5zY2FsZSA9IHNjYWxlXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG4gICAgXFxuICAgICMgU3ViZGl2aWRlIGhlYXZpbHkgZm9yIGZvbGRzXFxuICAgIGJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBvYmpcXG4gICAgYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nRURJVCcpXFxuICAgIGJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz00MClcXG4gICAgYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4gICAgXFxuICAgICMgQWRkIGZvbGRzIHZpYSB2ZXJ0ZXggZGlzcGxhY2VtZW50XFxuICAgIG1lc2ggPSBvYmouZGF0YVxcbiAgICBmb3IgdiBpbiBtZXNoLnZlcnRpY2VzOlxcbiAgICAgICAgeCwgeSwgeiA9IHYuY29cXG4gICAgICAgICMgQ3JlYXRlIGZvbGQtbGlrZSByaXBwbGVzIGFsb25nIHRoZSBjbG90aFxcbiAgICAgICAgZm9sZF96ID0gZm9sZF9pbnRlbnNpdHkgKiAoXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSkgKiAwLjUgK1xcbiAgICAgICAgICAgIG1hdGguc2luKHggKiBmb2xkX2ZyZXEgKiAyLjMgKyAxLjMpICogMC4zICtcXG4gICAgICAgICAgICBtYXRoLmNvcyh5ICogZm9sZF9mcmVxICogMC43KSAqIDAuMlxcbiAgICAgICAgKVxcbiAgICAgICAgIyBEYW1wZW4gZm9sZHMgbmVhciBhdHRhY2htZW50IGVkZ2UgKHRvcClcXG4gICAgICAgIGVkZ2VfZmFjdG9yID0gbWluKDEuMCwgYWJzKHopIC8gMS41KVxcbiAgICAgICAgdi5jby56ICs9IGZvbGRfeiAqIGVkZ2VfZmFjdG9yXFxuICAgIFxcbiAgICAjIEFkZCBzb2xpZGlmeSBtb2RpZmllciBmb3IgdGhpY2tuZXNzXFxuICAgIG1vZCA9IG9iai5tb2RpZmllcnMubmV3KG5hbWU9XFxcIlNvbGlkaWZ5XFxcIiwgdHlwZT0nU09MSURJRlknKVxcbiAgICBtb2QudGhpY2tuZXNzID0gMC4wMTVcXG4gICAgbW9kLm9mZnNldCA9IDBcXG4gICAgXFxuICAgICMgU21vb3RoIHNoYWRpbmdcXG4gICAgYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG4gICAgXFxuICAgIHJldHVybiBvYmpcXG5cXG4jIC0tLSBSZWQgdmVsdmV0IGNsb3RoIChsZWZ0IHNpZGUsIGRyYXBlZCBmcm9tIHRhYmxlIGVkZ2UpIC0tLVxcbnJlZF9jbG90aCA9IGNyZWF0ZV9kcmFwZWRfY2xvdGgoXFxuICAgIFxcXCJSZWRDbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgtMi4yLCAtMS41LCAwLjAyKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMy41LCAzLjAsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjEyLFxcbiAgICBmb2xkX2ZyZXE9NlxcbilcXG5cXG4jIC0tLSBHcmVlbiB2ZWx2ZXQgY2xvdGggKHJpZ2h0IHNpZGUsIG9uIHRhYmxlIHN1cmZhY2UpIC0tLVxcbmdyZWVuX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIkdyZWVuQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMi4wLCAwLjMsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgbWF0aC5yYWRpYW5zKDgpKSxcXG4gICAgc2NhbGU9KDMuMCwgMi44LCAxKSxcXG4gICAgZm9sZF9pbnRlbnNpdHk9MC4wOCxcXG4gICAgZm9sZF9mcmVxPTdcXG4pXFxuXFxuIyAtLS0gV2hpdGUvZ3JleSBsaW5lbiBydW5uZXIgKGNlbnRlciwgYmV0d2VlbiByZWQgYW5kIGdyZWVuIC0gQ29ybmVsbCBuZXV0cmFsKSAtLS1cXG53aGl0ZV9jbG90aCA9IGNyZWF0ZV9kcmFwZWRfY2xvdGgoXFxuICAgIFxcXCJXaGl0ZUNsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KDAuMCwgLTAuMiwgMC4wMyksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCAwKSxcXG4gICAgc2NhbGU9KDIuNSwgMi4yLCAxKSxcXG4gICAgZm9sZF9pbnRlbnNpdHk9MC4wNCxcXG4gICAgZm9sZF9mcmVxPTEwXFxuKVxcblxcbnByaW50KFxcXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9vYmplY3RzXFxcIjogW1xcXCJSZWRDbG90aFxcXCIsIFxcXCJHcmVlbkNsb3RoXFxcIiwgXFxcIldoaXRlQ2xvdGhcXFwiXX1cXG5cIn0ifX1dLCJyZWFzb25pbmdfZGV0YWlscyI6W3sidHlwZSI6InJlYXNvbmluZy50ZXh0IiwidGV4dCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGRyYXBlZCBjbG90aHMuIEknbGwgY3JlYXRlIGEgcmVkIHZlbHZldCBjbG90aCBkcmFwaW5nIG9uIHRoZSBsZWZ0IGFuZCBhIGdyZWVuIG9uZSBvbiB0aGUgcmlnaHQsIHdpdGggZm9sZCBzdHJ1Y3R1cmUuIEknbGwgdXNlIGEgc3ViZGl2aWRlZCBwbGFuZSB3aXRoIHNvbWUgZGlzcGxhY2VtZW50IGZvciBmb2xkcy4iLCJmb3JtYXQiOiJ1bmtub3duIiwiaW5kZXgiOjB9XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6NzAyNywiY29tcGxldGlvbl90b2tlbnMiOjgwNywidG90YWxfdG9rZW5zIjo3ODM0LCJjb3N0IjowLjAwNDMyMDAwMDYsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6NjA4MCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDQzMjAwMDA2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDAxOTQ0NTE1NCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAyMzc1NDg1Mn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6NTAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector, Matrix\n\nrandom.seed(42)\n\n# ============================================================\n# DRAPED CLOTHS with fold structure\n# ============================================================\n\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\n    \"\"\"Create a draped cloth plane with fold-like displacement.\"\"\"\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\n    obj = bpy.context.active_object\n    obj.name = name\n    obj.rotation_euler = rotation\n    obj.scale = scale\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n    \n    # Subdivide heavily for folds\n    bpy.context.view_layer.objects.active = obj\n    bpy.ops.object.mode_set(mode='EDIT')\n    bpy.ops.mesh.select_all(action='SELECT')\n    bpy.ops.mesh.subdivide(number_cuts=40)\n    bpy.ops.object.mode_set(mode='OBJECT')\n    \n    # Add folds via vertex displacement\n    mesh = obj.data\n    for v in mesh.vertices:\n        x, y, z = v.co\n        # Create fold-like ripples along the cloth\n        fold_z = fold_intensity * (\n            math.sin(x * fold_freq) * 0.5 +\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\n            math.cos(y * fold_freq * 0.7) * 0.2\n        )\n        # Dampen folds near attachment edge (top)\n        edge_factor = min(1.0, abs(z) / 1.5)\n        v.co.z += fold_z * edge_factor\n    \n    # Add solidify modifier for thickness\n    mod = obj.modifiers.new(name=\"Solidify\", type='SOLIDIFY')\n    mod.thickness = 0.015\n    mod.offset = 0\n    \n    # Smooth shading\n    bpy.ops.object.shade_smooth()\n    \n    return obj\n\n# --- Red velvet cloth (left side, draped from table edge) ---\nred_cloth = create_draped_cloth(\n    \"RedCloth\",\n    location=(-2.2, -1.5, 0.02),\n    rotation=(0, 0, 0),\n    scale=(3.5, 3.0, 1),\n    fold_intensity=0.12,\n    fold_freq=6\n)\n\n# --- Green velvet cloth (right side, on table surface) ---\ngreen_cloth = create_draped_cloth(\n    \"GreenCloth\",\n    location=(2.0, 0.3, 0.02),\n    rotation=(0, 0, math.radians(8)),\n    scale=(3.0, 2.8, 1),\n    fold_intensity=0.08,\n    fold_freq=7\n)\n\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\nwhite_cloth = create_draped_cloth(\n    \"WhiteCloth\",\n    location=(0.0, -0.2, 0.03),\n    rotation=(0, 0, 0),\n    scale=(2.5, 2.2, 1),\n    fold_intensity=0.04,\n    fold_freq=10\n)\n\nprint(\"Draped cloths built.\")\nresult = {\"cloth_objects\": [\"RedCloth\", \"GreenCloth\", \"WhiteCloth\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}", "parse_error": null}], "tokens_in": 7027, "tokens_out": 807, "cost_usd": 0.0043200006, "cached_tokens": 6080}, "error": null}
{"ts": "2026-07-17T14:55:13.555547+00:00", "type": "assistant", "text": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector, Matrix\n\nrandom.seed(42)\n\n# ============================================================\n# DRAPED CLOTHS with fold structure\n# ============================================================\n\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\n    \"\"\"Create a draped cloth plane with fold-like displacement.\"\"\"\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\n    obj = bpy.context.active_object\n    obj.name = name\n    obj.rotation_euler = rotation\n    obj.scale = scale\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n    \n    # Subdivide heavily for folds\n    bpy.context.view_layer.objects.active = obj\n    bpy.ops.object.mode_set(mode='EDIT')\n    bpy.ops.mesh.select_all(action='SELECT')\n    bpy.ops.mesh.subdivide(number_cuts=40)\n    bpy.ops.object.mode_set(mode='OBJECT')\n    \n    # Add folds via vertex displacement\n    mesh = obj.data\n    for v in mesh.vertices:\n        x, y, z = v.co\n        # Create fold-like ripples along the cloth\n        fold_z = fold_intensity * (\n            math.sin(x * fold_freq) * 0.5 +\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\n            math.cos(y * fold_freq * 0.7) * 0.2\n        )\n        # Dampen folds near attachment edge (top)\n        edge_factor = min(1.0, abs(z) / 1.5)\n        v.co.z += fold_z * edge_factor\n    \n    # Add solidify modifier for thickness\n    mod = obj.modifiers.new(name=\"Solidify\", type='SOLIDIFY')\n    mod.thickness = 0.015\n    mod.offset = 0\n    \n    # Smooth shading\n    bpy.ops.object.shade_smooth()\n    \n    return obj\n\n# --- Red velvet cloth (left side, draped from table edge) ---\nred_cloth = create_draped_cloth(\n    \"RedCloth\",\n    location=(-2.2, -1.5, 0.02),\n    rotation=(0, 0, 0),\n    scale=(3.5, 3.0, 1),\n    fold_intensity=0.12,\n    fold_freq=6\n)\n\n# --- Green velvet cloth (right side, on table surface) ---\ngreen_cloth = create_draped_cloth(\n    \"GreenCloth\",\n    location=(2.0, 0.3, 0.02),\n    rotation=(0, 0, math.radians(8)),\n    scale=(3.0, 2.8, 1),\n    fold_intensity=0.08,\n    fold_freq=7\n)\n\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\nwhite_cloth = create_draped_cloth(\n    \"WhiteCloth\",\n    location=(0.0, -0.2, 0.03),\n    rotation=(0, 0, 0),\n    scale=(2.5, 2.2, 1),\n    fold_intensity=0.04,\n    fold_freq=10\n)\n\nprint(\"Draped cloths built.\")\nresult = {\"cloth_objects\": [\"RedCloth\", \"GreenCloth\", \"WhiteCloth\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:55:13.555547+00:00", "type": "tool_call", "id": "chatcmpl-tool-a446a83c48a104cb", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector, Matrix\n\nrandom.seed(42)\n\n# ============================================================\n# DRAPED CLOTHS with fold structure\n# ============================================================\n\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\n    \"\"\"Create a draped cloth plane with fold-like displacement.\"\"\"\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\n    obj = bpy.context.active_object\n    obj.name = name\n    obj.rotation_euler = rotation\n    obj.scale = scale\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n    \n    # Subdivide heavily for folds\n    bpy.context.view_layer.objects.active = obj\n    bpy.ops.object.mode_set(mode='EDIT')\n    bpy.ops.mesh.select_all(action='SELECT')\n    bpy.ops.mesh.subdivide(number_cuts=40)\n    bpy.ops.object.mode_set(mode='OBJECT')\n    \n    # Add folds via vertex displacement\n    mesh = obj.data\n    for v in mesh.vertices:\n        x, y, z = v.co\n        # Create fold-like ripples along the cloth\n        fold_z = fold_intensity * (\n            math.sin(x * fold_freq) * 0.5 +\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\n            math.cos(y * fold_freq * 0.7) * 0.2\n        )\n        # Dampen folds near attachment edge (top)\n        edge_factor = min(1.0, abs(z) / 1.5)\n        v.co.z += fold_z * edge_factor\n    \n    # Add solidify modifier for thickness\n    mod = obj.modifiers.new(name=\"Solidify\", type='SOLIDIFY')\n    mod.thickness = 0.015\n    mod.offset = 0\n    \n    # Smooth shading\n    bpy.ops.object.shade_smooth()\n    \n    return obj\n\n# --- Red velvet cloth (left side, draped from table edge) ---\nred_cloth = create_draped_cloth(\n    \"RedCloth\",\n    location=(-2.2, -1.5, 0.02),\n    rotation=(0, 0, 0),\n    scale=(3.5, 3.0, 1),\n    fold_intensity=0.12,\n    fold_freq=6\n)\n\n# --- Green velvet cloth (right side, on table surface) ---\ngreen_cloth = create_draped_cloth(\n    \"GreenCloth\",\n    location=(2.0, 0.3, 0.02),\n    rotation=(0, 0, math.radians(8)),\n    scale=(3.0, 2.8, 1),\n    fold_intensity=0.08,\n    fold_freq=7\n)\n\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\nwhite_cloth = create_draped_cloth(\n    \"WhiteCloth\",\n    location=(0.0, -0.2, 0.03),\n    rotation=(0, 0, 0),\n    scale=(2.5, 2.2, 1),\n    fold_intensity=0.04,\n    fold_freq=10\n)\n\nprint(\"Draped cloths built.\")\nresult = {\"cloth_objects\": [\"RedCloth\", \"GreenCloth\", \"WhiteCloth\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}
{"ts": "2026-07-17T14:55:14.544763+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:55:33.836420+00:00", "type": "llm_call", "call_index": 5, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:55:14.544763+00:00", "finished_at": "2026-07-17T14:55:33.836420+00:00", "duration_s": 19.280999999988126, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:55:14.544763+00:00", "finished_at": "2026-07-17T14:55:33.836420+00:00", "duration_s": 19.280999999988126, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "33538", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:55:16 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300115-VLTkJBWZgt41mFLS0Q5Q", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1627697dec9b-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300115-VLTkJBWZgt41mFLS0Q5Q\",\"object\":\"chat.completion\",\"created\":1784300115,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":7848,\"completion_tokens\":803,\"total_tokens\":8651,\"cost\":0.00439383144,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":6976,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00439383144,\"upstream_inference_prompt_cost\":0.00203012064,\"upstream_inference_completions_cost\":0.0023637108},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAwMTE1LVZMVGtKQldaZ3Q0MW1GTFMwUTVRIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMDExNSwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6Nzg0OCwiY29tcGxldGlvbl90b2tlbnMiOjgwMywidG90YWxfdG9rZW5zIjo4NjUxLCJjb3N0IjowLjAwNDM5MzgzMTQ0LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjY5NzYsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA0MzkzODMxNDQsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDIwMzAxMjA2NCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAyMzYzNzEwOH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\n# ============================================================\n# THE UTAH TEAPOT — the hero\n# Classic squat proportions, built from profile curves revolved\n# ============================================================\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# --- Teapot Body: lathe a profile ---\n# Profile points (radius, height) tracing the classic teapot body silhouette\nbody_profile = [\n    (0.00, 0.00),   # center bottom\n    (0.35, 0.00),   # base edge\n    (0.55, 0.02),   # \n    (0.70, 0.08),   # bulge start\n    (0.82, 0.20),   # widest bulge lower\n    (0.88, 0.35),   # widest point\n    (0.87, 0.50),   # \n    (0.80, 0.65),   # tapering up\n    (0.70, 0.78),   # \n    (0.55, 0.88),   # shoulder\n    (0.40, 0.94),   # neck\n    (0.32, 0.98),   # lid seat\n    (0.30, 1.00),   # top opening edge\n]\n\n# Build the body as a lathed mesh\nmesh = bpy.data.meshes.new(\"TeapotBodyMesh\")\nbm = bmesh.new()\n\nsegments = 48\n# Create rings of vertices\nall_verts = []\nfor r, h in body_profile:\n    ring = []\n    if r < 0.001:\n        # single vertex at center (pole)\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\n# Create faces between rings\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = body_profile[ri]\n    rb, _ = body_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            # triangle fan\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nbody_obj = bpy.data.objects.new(\"TeapotBody\", mesh)\nlink_obj(body_obj)\nbpy.context.view_layer.objects.active = body_obj\nbpy.ops.object.shade_smooth()\n\n# Add subdivision surface for smoothness\nmod = body_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 2\nmod.render_levels = 3\n\nprint(\"Teapot body built.\")\nresult = {\"verts\": len(mesh.vertices), \"faces\": len(mesh.polygons)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}", "parse_error": null}], "tokens_in": 7848, "tokens_out": 803, "cost_usd": 0.00439383144, "cached_tokens": 6976}, "error": null}
{"ts": "2026-07-17T14:55:33.837924+00:00", "type": "assistant", "text": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\n# ============================================================\n# THE UTAH TEAPOT — the hero\n# Classic squat proportions, built from profile curves revolved\n# ============================================================\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# --- Teapot Body: lathe a profile ---\n# Profile points (radius, height) tracing the classic teapot body silhouette\nbody_profile = [\n    (0.00, 0.00),   # center bottom\n    (0.35, 0.00),   # base edge\n    (0.55, 0.02),   # \n    (0.70, 0.08),   # bulge start\n    (0.82, 0.20),   # widest bulge lower\n    (0.88, 0.35),   # widest point\n    (0.87, 0.50),   # \n    (0.80, 0.65),   # tapering up\n    (0.70, 0.78),   # \n    (0.55, 0.88),   # shoulder\n    (0.40, 0.94),   # neck\n    (0.32, 0.98),   # lid seat\n    (0.30, 1.00),   # top opening edge\n]\n\n# Build the body as a lathed mesh\nmesh = bpy.data.meshes.new(\"TeapotBodyMesh\")\nbm = bmesh.new()\n\nsegments = 48\n# Create rings of vertices\nall_verts = []\nfor r, h in body_profile:\n    ring = []\n    if r < 0.001:\n        # single vertex at center (pole)\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\n# Create faces between rings\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = body_profile[ri]\n    rb, _ = body_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            # triangle fan\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nbody_obj = bpy.data.objects.new(\"TeapotBody\", mesh)\nlink_obj(body_obj)\nbpy.context.view_layer.objects.active = body_obj\nbpy.ops.object.shade_smooth()\n\n# Add subdivision surface for smoothness\nmod = body_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 2\nmod.render_levels = 3\n\nprint(\"Teapot body built.\")\nresult = {\"verts\": len(mesh.vertices), \"faces\": len(mesh.polygons)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:55:33.837924+00:00", "type": "tool_call", "id": "chatcmpl-tool-8f91ff705ec7e347", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\n# ============================================================\n# THE UTAH TEAPOT — the hero\n# Classic squat proportions, built from profile curves revolved\n# ============================================================\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# --- Teapot Body: lathe a profile ---\n# Profile points (radius, height) tracing the classic teapot body silhouette\nbody_profile = [\n    (0.00, 0.00),   # center bottom\n    (0.35, 0.00),   # base edge\n    (0.55, 0.02),   # \n    (0.70, 0.08),   # bulge start\n    (0.82, 0.20),   # widest bulge lower\n    (0.88, 0.35),   # widest point\n    (0.87, 0.50),   # \n    (0.80, 0.65),   # tapering up\n    (0.70, 0.78),   # \n    (0.55, 0.88),   # shoulder\n    (0.40, 0.94),   # neck\n    (0.32, 0.98),   # lid seat\n    (0.30, 1.00),   # top opening edge\n]\n\n# Build the body as a lathed mesh\nmesh = bpy.data.meshes.new(\"TeapotBodyMesh\")\nbm = bmesh.new()\n\nsegments = 48\n# Create rings of vertices\nall_verts = []\nfor r, h in body_profile:\n    ring = []\n    if r < 0.001:\n        # single vertex at center (pole)\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\n# Create faces between rings\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = body_profile[ri]\n    rb, _ = body_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            # triangle fan\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nbody_obj = bpy.data.objects.new(\"TeapotBody\", mesh)\nlink_obj(body_obj)\nbpy.context.view_layer.objects.active = body_obj\nbpy.ops.object.shade_smooth()\n\n# Add subdivision surface for smoothness\nmod = body_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 2\nmod.render_levels = 3\n\nprint(\"Teapot body built.\")\nresult = {\"verts\": len(mesh.vertices), \"faces\": len(mesh.polygons)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}
{"ts": "2026-07-17T14:55:33.909649+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:56:14.306852+00:00", "type": "llm_call", "call_index": 6, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:55:33.909649+00:00", "finished_at": "2026-07-17T14:56:14.306852+00:00", "duration_s": 40.40700000000652, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:55:33.909649+00:00", "finished_at": "2026-07-17T14:56:14.306852+00:00", "duration_s": 40.40700000000652, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "36786", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:55:36 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300134-9r1tLIbV5kGCyFreohEe", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca16a07a2df3fc-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300134-9r1tLIbV5kGCyFreohEe\",\"object\":\"chat.completion\",\"created\":1784300134,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":8699,\"completion_tokens\":1542,\"total_tokens\":10241,\"cost\":0.00673166532,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":7808,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00673166532,\"upstream_inference_prompt_cost\":0.00219263412,\"upstream_inference_completions_cost\":0.0045390312},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMDEzNC05cjF0TEliVjVrR0N5RnJlb2hFZSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDAxMzQsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgdGhlIHRlYXBvdCBzcG91dCwgaGFuZGxlLCBhbmQgbGlkLiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC04NjU1ZmQzNGRjNWQzZDE1IiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIFNQT1VUIOKAlCBjdXJ2ZWQgdHViZVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBUaGUgc3BvdXQgcmlzZXMgZnJvbSB0aGUgbG93ZXIgYm9keSwgY3VydmVzIG91dHdhcmQgYW5kIHVwXFxuXFxuc3BvdXRfY3VydmVfZGF0YSA9IGJweS5kYXRhLmN1cnZlcy5uZXcoJ1RlYXBvdFNwb3V0Q3VydmUnLCB0eXBlPSdDVVJWRScpXFxuc3BvdXRfY3VydmVfZGF0YS5kaW1lbnNpb25zID0gJzNEJ1xcbnNwb3V0X2N1cnZlX2RhdGEucmVzb2x1dGlvbl91ID0gMTZcXG5zcG91dF9jdXJ2ZV9kYXRhLmJldmVsX2RlcHRoID0gMC4wICAjIHdlJ2xsIGJ1aWxkIG1lc2ggbWFudWFsbHlcXG5cXG5zcGxpbmUgPSBzcG91dF9jdXJ2ZV9kYXRhLnNwbGluZXMubmV3KCdCRVpJRVInKVxcbiMgQ29udHJvbCBwb2ludHMgdHJhY2luZyB0aGUgc3BvdXQgcGF0aCAoaW4gYm9keS1sb2NhbCBzcGFjZSlcXG4jIFNwb3V0IGV4aXRzIGJvZHkgYXJvdW5kICgwLjg1LCAwLCAwLjI1KSwgY3VydmVzIHVwIGFuZCBvdXRcXG5zcG91dF9wb2ludHMgPSBbXFxuICAgICgwLjgyLCAwLCAwLjIyKSwgICAjIGJhc2UgYXQgYm9keVxcbiAgICAoMS4wNSwgMCwgMC4zMCksICAgIyBjdXJ2aW5nIG91dFxcbiAgICAoMS4yNSwgMCwgMC40NSksICAgIyBtaWRcXG4gICAgKDEuMzgsIDAsIDAuNjIpLCAgICMgY3VydmluZyB1cFxcbiAgICAoMS40MiwgMCwgMC44MCksICAgIyBuZWFyIHRpcFxcbiAgICAoMS40MCwgMCwgMC45MiksICAgIyB0aXBcXG5dXFxuc3BsaW5lLmJlemllcl9wb2ludHMuYWRkKGxlbihzcG91dF9wb2ludHMpIC0gMSlcXG5mb3IgaSwgcHQgaW4gZW51bWVyYXRlKHNwb3V0X3BvaW50cyk6XFxuICAgIGJwID0gc3BsaW5lLmJlemllcl9wb2ludHNbaV1cXG4gICAgYnAuY28gPSBwdFxcbiAgICBicC5oYW5kbGVfbGVmdF90eXBlID0gJ0FVVE8nXFxuICAgIGJwLmhhbmRsZV9yaWdodF90eXBlID0gJ0FVVE8nXFxuXFxuc3BvdXRfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoJ1RlYXBvdFNwb3V0Jywgc3BvdXRfY3VydmVfZGF0YSlcXG5saW5rX29iaihzcG91dF9vYmopXFxuXFxuIyBDb252ZXJ0IGN1cnZlIHRvIG1lc2gsIHRoZW4gdGFwZXIgaXRcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J0RFU0VMRUNUJylcXG5zcG91dF9vYmouc2VsZWN0X3NldChUcnVlKVxcbmJweS5vcHMub2JqZWN0LmNvbnZlcnQodGFyZ2V0PSdNRVNIJylcXG5cXG5zcG91dF9tZXNoID0gc3BvdXRfb2JqLmRhdGFcXG4jIFRhcGVyIHRoZSBzcG91dDogbWFrZSBpdCB3aWRlciBhdCBiYXNlLCBuYXJyb3dlciBhdCB0aXBcXG4jIFRoZSBtZXNoIGZyb20gY3VydmUgY29udmVyc2lvbiBoYXMgdmVydGljZXMgYWxvbmcgdGhlIHBhdGhcXG4jIFdlJ2xsIHNjYWxlIGJhc2VkIG9uIHogaGVpZ2h0XFxubWluX3ogPSBtaW4odi5jby56IGZvciB2IGluIHNwb3V0X21lc2gudmVydGljZXMpXFxubWF4X3ogPSBtYXgodi5jby56IGZvciB2IGluIHNwb3V0X21lc2gudmVydGljZXMpXFxuel9yYW5nZSA9IG1heF96IC0gbWluX3pcXG5cXG5mb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzOlxcbiAgICAjIG5vcm1hbGl6ZSBwb3NpdGlvbiBhbG9uZyBwYXRoICgwPWJhc2UsIDE9dGlwKVxcbiAgICB0ID0gKHYuY28ueiAtIG1pbl96KSAvIG1heCh6X3JhbmdlLCAwLjAwMSlcXG4gICAgIyBSYWRpdXMgdGFwZXI6IHRoaWNrIGF0IGJhc2UsIG5hcnJvdyBhdCB0aXBcXG4gICAgIyBBbHNvIHdpZGVuIHRoZSBvcGVuaW5nIGF0IHRoZSB2ZXJ5IHRpcCAobGlwKVxcbiAgICBpZiB0ID4gMC44NTpcXG4gICAgICAgICMgZmxhcmUgc2xpZ2h0bHkgYXQgdGhlIHNwb3V0IGxpcFxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTIgKyAodCAtIDAuODUpICogMC41XFxuICAgIGVsc2U6XFxuICAgICAgICByYWRpdXNfZmFjdG9yID0gMC4xOCAtIHQgKiAwLjA2XFxuICAgICMgU2NhbGUgeCx5IGFyb3VuZCB0aGUgcGF0aCBjZW50ZXIgKGFwcHJveGltYXRlIGJ5IHNjYWxpbmcgZnJvbSBsb2NhbCBheGlzKVxcbiAgICAjIFRoZSBzcG91dCBleHRlbmRzIGFsb25nICt4LCBzbyBzY2FsZSB5IGFuZCB6LW9mZnNldFxcbiAgICBjZW50ZXJfeCA9IDEuMSAgIyBhcHByb3hpbWF0ZSBwYXRoIGNlbnRlclxcbiAgICB2LmNvLnkgKj0gKHJhZGl1c19mYWN0b3IgLyAwLjE4KVxcbiAgICB2LmNvLnogPSB2LmNvLnogICMga2VlcCB6XFxuXFxuIyBBY3R1YWxseSwgbGV0IG1lIHJlYnVpbGQgdGhlIHNwb3V0IG1vcmUgY2FyZWZ1bGx5IHdpdGggYSBwcm9wZXIgdHViZVxcbmJweS5kYXRhLm9iamVjdHMucmVtb3ZlKHNwb3V0X29iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyAtLS0gUmVidWlsZCBzcG91dCBhcyBhIHByb3BlciB0YXBlcmVkIHR1YmUgLS0tXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdFNwb3V0TWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIFNwb3V0IGNlbnRlcmxpbmUgcG9pbnRzXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoMC44MCwgMCwgMC4yMCkpLFxcbiAgICBWZWN0b3IoKDEuMDAsIDAsIDAuMjYpKSxcXG4gICAgVmVjdG9yKCgxLjIwLCAwLCAwLjM4KSksXFxuICAgIFZlY3RvcigoMS4zNCwgMCwgMC41NSkpLFxcbiAgICBWZWN0b3IoKDEuNDAsIDAsIDAuNzQpKSxcXG4gICAgVmVjdG9yKCgxLjM4LCAwLCAwLjkwKSksXFxuXVxcbiMgUmFkaWkgYXQgZWFjaCBwb2ludFxcbnBhdGhfcmFkaWkgPSBbMC4xNiwgMC4xNCwgMC4xMiwgMC4xMCwgMC4wOSwgMC4xMV0gICMgc2xpZ2h0IGZsYXJlIGF0IHRpcFxcblxcbiMgR2VuZXJhdGUgcmluZ3NcXG5yaW5ncyA9IFtdXFxuZm9yIHBpLCAocCwgcikgaW4gZW51bWVyYXRlKHppcChwYXRoX3BvaW50cywgcGF0aF9yYWRpaSkpOlxcbiAgICByaW5nID0gW11cXG4gICAgIyBDb21wdXRlIHRhbmdlbnQgKGRpcmVjdGlvbiBhbG9uZyBwYXRoKVxcbiAgICBpZiBwaSA9PSAwOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1sxXSAtIHBhdGhfcG9pbnRzWzBdKS5ub3JtYWxpemVkKClcXG4gICAgZWxpZiBwaSA9PSBsZW4ocGF0aF9wb2ludHMpIC0gMTpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbLTFdIC0gcGF0aF9wb2ludHNbLTJdKS5ub3JtYWxpemVkKClcXG4gICAgZWxzZTpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbcGkrMV0gLSBwYXRoX3BvaW50c1twaS0xXSkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICAjIEJ1aWxkIGEgZnJhbWUgcGVycGVuZGljdWxhciB0byB0YW5nZW50XFxuICAgICMgU3BvdXQgZ29lcyByb3VnaGx5IGluICt4IGFuZCAreiwgc28gbm9ybWFsIHBsYW5lIHNwYW5zIHkgYW5kIChwZXJwIGluIHh6KVxcbiAgICB1cCA9IFZlY3RvcigoMCwgMCwgMSkpXFxuICAgIGlmIGFicyh0YW5nZW50LmRvdCh1cCkpID4gMC45OlxcbiAgICAgICAgdXAgPSBWZWN0b3IoKDEsIDAsIDApKVxcbiAgICByaWdodCA9IHRhbmdlbnQuY3Jvc3ModXApLm5vcm1hbGl6ZWQoKVxcbiAgICB1cCA9IHJpZ2h0LmNyb3NzKHRhbmdlbnQpLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICBvZmZzZXQgPSAobWF0aC5jb3MoYW5nbGUpICogcmlnaHQgKyBtYXRoLnNpbihhbmdsZSkgKiB1cCkgKiByXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KHAgKyBvZmZzZXQpXFxuICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICByaW5ncy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG4jIENvbm5lY3QgcmluZ3Mgd2l0aCBmYWNlc1xcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuIyBDYXAgdGhlIHRpcCAodG9wKSAtIHRoZSBzcG91dCBvcGVuaW5nXFxudGlwX3JpbmcgPSByaW5nc1stMV1cXG5jZW50ZXIgPSBzdW0oKHYuY28gZm9yIHYgaW4gdGlwX3JpbmcpLCBWZWN0b3IoKSkgLyBsZW4odGlwX3JpbmcpXFxuIyBEb24ndCBjYXAgLSBsZWF2ZSBvcGVuIGFzIGEgc3BvdXQgb3BlbmluZywgYnV0IGFkZCBhIHNsaWdodCByaW1cXG4jIEFjdHVhbGx5IGNhcCB0aGUgYmFzZSB3aGVyZSBpdCBtZWV0cyB0aGUgYm9keVxcbmJhc2VfcmluZyA9IHJpbmdzWzBdXFxuYmFzZV9jZW50ZXIgPSBzdW0oKHYuY28gZm9yIHYgaW4gYmFzZV9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKGJhc2VfcmluZylcXG4jIExlYXZlIGJvdGggb3BlbiBmb3Igbm93IChiYXNlIG1lcmdlcyBpbnRvIGJvZHkpXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RTcG91dFxcXCIsIG1lc2gpXFxubGlua19vYmooc3BvdXRfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBzcG91dF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IHNwb3V0X29iai5tb2RpZmllcnMubmV3KFxcXCJTdWJzdXJmXFxcIiwgJ1NVQlNVUkYnKVxcbm1vZC5sZXZlbHMgPSAxXFxubW9kLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzcG91dCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3BvdXRfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6ODY5OSwiY29tcGxldGlvbl90b2tlbnMiOjE1NDIsInRvdGFsX3Rva2VucyI6MTAyNDEsImNvc3QiOjAuMDA2NzMxNjY1MzIsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6NzgwOCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDY3MzE2NjUzMiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwMjE5MjYzNDEyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDQ1MzkwMzEyfSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# TEAPOT SPOUT — curved tube\n# ============================================================\n# The spout rises from the lower body, curves outward and up\n\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\nspout_curve_data.dimensions = '3D'\nspout_curve_data.resolution_u = 16\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\n\nspline = spout_curve_data.splines.new('BEZIER')\n# Control points tracing the spout path (in body-local space)\n# Spout exits body around (0.85, 0, 0.25), curves up and out\nspout_points = [\n    (0.82, 0, 0.22),   # base at body\n    (1.05, 0, 0.30),   # curving out\n    (1.25, 0, 0.45),   # mid\n    (1.38, 0, 0.62),   # curving up\n    (1.42, 0, 0.80),   # near tip\n    (1.40, 0, 0.92),   # tip\n]\nspline.bezier_points.add(len(spout_points) - 1)\nfor i, pt in enumerate(spout_points):\n    bp = spline.bezier_points[i]\n    bp.co = pt\n    bp.handle_left_type = 'AUTO'\n    bp.handle_right_type = 'AUTO'\n\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\nlink_obj(spout_obj)\n\n# Convert curve to mesh, then taper it\nbpy.context.view_layer.objects.active = spout_obj\nbpy.ops.object.select_all(action='DESELECT')\nspout_obj.select_set(True)\nbpy.ops.object.convert(target='MESH')\n\nspout_mesh = spout_obj.data\n# Taper the spout: make it wider at base, narrower at tip\n# The mesh from curve conversion has vertices along the path\n# We'll scale based on z height\nmin_z = min(v.co.z for v in spout_mesh.vertices)\nmax_z = max(v.co.z for v in spout_mesh.vertices)\nz_range = max_z - min_z\n\nfor v in spout_mesh.vertices:\n    # normalize position along path (0=base, 1=tip)\n    t = (v.co.z - min_z) / max(z_range, 0.001)\n    # Radius taper: thick at base, narrow at tip\n    # Also widen the opening at the very tip (lip)\n    if t > 0.85:\n        # flare slightly at the spout lip\n        radius_factor = 0.12 + (t - 0.85) * 0.5\n    else:\n        radius_factor = 0.18 - t * 0.06\n    # Scale x,y around the path center (approximate by scaling from local axis)\n    # The spout extends along +x, so scale y and z-offset\n    center_x = 1.1  # approximate path center\n    v.co.y *= (radius_factor / 0.18)\n    v.co.z = v.co.z  # keep z\n\n# Actually, let me rebuild the spout more carefully with a proper tube\nbpy.data.objects.remove(spout_obj, do_unlink=True)\n\n# --- Rebuild spout as a proper tapered tube ---\nmesh = bpy.data.meshes.new(\"TeapotSpoutMesh\")\nbm = bmesh.new()\n\nsegments = 24\n# Spout centerline points\npath_points = [\n    Vector((0.80, 0, 0.20)),\n    Vector((1.00, 0, 0.26)),\n    Vector((1.20, 0, 0.38)),\n    Vector((1.34, 0, 0.55)),\n    Vector((1.40, 0, 0.74)),\n    Vector((1.38, 0, 0.90)),\n]\n# Radii at each point\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\n\n# Generate rings\nrings = []\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\n    ring = []\n    # Compute tangent (direction along path)\n    if pi == 0:\n        tangent = (path_points[1] - path_points[0]).normalized()\n    elif pi == len(path_points) - 1:\n        tangent = (path_points[-1] - path_points[-2]).normalized()\n    else:\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\n    \n    # Build a frame perpendicular to tangent\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\n    up = Vector((0, 0, 1))\n    if abs(tangent.dot(up)) > 0.9:\n        up = Vector((1, 0, 0))\n    right = tangent.cross(up).normalized()\n    up = right.cross(tangent).normalized()\n    \n    for i in range(segments):\n        angle = (i / segments) * math.tau\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\n        v = bm.verts.new(p + offset)\n        ring.append(v)\n    rings.append(ring)\n\nbm.verts.ensure_lookup_table()\n\n# Connect rings with faces\nfor ri in range(len(rings) - 1):\n    for i in range(segments):\n        j = (i + 1) % segments\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\n\n# Cap the tip (top) - the spout opening\ntip_ring = rings[-1]\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\n# Don't cap - leave open as a spout opening, but add a slight rim\n# Actually cap the base where it meets the body\nbase_ring = rings[0]\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\n# Leave both open for now (base merges into body)\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nspout_obj = bpy.data.objects.new(\"TeapotSpout\", mesh)\nlink_obj(spout_obj)\nbpy.context.view_layer.objects.active = spout_obj\nbpy.ops.object.shade_smooth()\n\nmod = spout_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\nprint(\"Teapot spout built.\")\nresult = {\"spout_verts\": len(mesh.vertices)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}", "parse_error": null}], "tokens_in": 8699, "tokens_out": 1542, "cost_usd": 0.00673166532, "cached_tokens": 7808}, "error": null}
{"ts": "2026-07-17T14:56:14.308055+00:00", "type": "assistant", "text": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# TEAPOT SPOUT — curved tube\n# ============================================================\n# The spout rises from the lower body, curves outward and up\n\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\nspout_curve_data.dimensions = '3D'\nspout_curve_data.resolution_u = 16\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\n\nspline = spout_curve_data.splines.new('BEZIER')\n# Control points tracing the spout path (in body-local space)\n# Spout exits body around (0.85, 0, 0.25), curves up and out\nspout_points = [\n    (0.82, 0, 0.22),   # base at body\n    (1.05, 0, 0.30),   # curving out\n    (1.25, 0, 0.45),   # mid\n    (1.38, 0, 0.62),   # curving up\n    (1.42, 0, 0.80),   # near tip\n    (1.40, 0, 0.92),   # tip\n]\nspline.bezier_points.add(len(spout_points) - 1)\nfor i, pt in enumerate(spout_points):\n    bp = spline.bezier_points[i]\n    bp.co = pt\n    bp.handle_left_type = 'AUTO'\n    bp.handle_right_type = 'AUTO'\n\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\nlink_obj(spout_obj)\n\n# Convert curve to mesh, then taper it\nbpy.context.view_layer.objects.active = spout_obj\nbpy.ops.object.select_all(action='DESELECT')\nspout_obj.select_set(True)\nbpy.ops.object.convert(target='MESH')\n\nspout_mesh = spout_obj.data\n# Taper the spout: make it wider at base, narrower at tip\n# The mesh from curve conversion has vertices along the path\n# We'll scale based on z height\nmin_z = min(v.co.z for v in spout_mesh.vertices)\nmax_z = max(v.co.z for v in spout_mesh.vertices)\nz_range = max_z - min_z\n\nfor v in spout_mesh.vertices:\n    # normalize position along path (0=base, 1=tip)\n    t = (v.co.z - min_z) / max(z_range, 0.001)\n    # Radius taper: thick at base, narrow at tip\n    # Also widen the opening at the very tip (lip)\n    if t > 0.85:\n        # flare slightly at the spout lip\n        radius_factor = 0.12 + (t - 0.85) * 0.5\n    else:\n        radius_factor = 0.18 - t * 0.06\n    # Scale x,y around the path center (approximate by scaling from local axis)\n    # The spout extends along +x, so scale y and z-offset\n    center_x = 1.1  # approximate path center\n    v.co.y *= (radius_factor / 0.18)\n    v.co.z = v.co.z  # keep z\n\n# Actually, let me rebuild the spout more carefully with a proper tube\nbpy.data.objects.remove(spout_obj, do_unlink=True)\n\n# --- Rebuild spout as a proper tapered tube ---\nmesh = bpy.data.meshes.new(\"TeapotSpoutMesh\")\nbm = bmesh.new()\n\nsegments = 24\n# Spout centerline points\npath_points = [\n    Vector((0.80, 0, 0.20)),\n    Vector((1.00, 0, 0.26)),\n    Vector((1.20, 0, 0.38)),\n    Vector((1.34, 0, 0.55)),\n    Vector((1.40, 0, 0.74)),\n    Vector((1.38, 0, 0.90)),\n]\n# Radii at each point\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\n\n# Generate rings\nrings = []\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\n    ring = []\n    # Compute tangent (direction along path)\n    if pi == 0:\n        tangent = (path_points[1] - path_points[0]).normalized()\n    elif pi == len(path_points) - 1:\n        tangent = (path_points[-1] - path_points[-2]).normalized()\n    else:\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\n    \n    # Build a frame perpendicular to tangent\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\n    up = Vector((0, 0, 1))\n    if abs(tangent.dot(up)) > 0.9:\n        up = Vector((1, 0, 0))\n    right = tangent.cross(up).normalized()\n    up = right.cross(tangent).normalized()\n    \n    for i in range(segments):\n        angle = (i / segments) * math.tau\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\n        v = bm.verts.new(p + offset)\n        ring.append(v)\n    rings.append(ring)\n\nbm.verts.ensure_lookup_table()\n\n# Connect rings with faces\nfor ri in range(len(rings) - 1):\n    for i in range(segments):\n        j = (i + 1) % segments\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\n\n# Cap the tip (top) - the spout opening\ntip_ring = rings[-1]\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\n# Don't cap - leave open as a spout opening, but add a slight rim\n# Actually cap the base where it meets the body\nbase_ring = rings[0]\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\n# Leave both open for now (base merges into body)\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nspout_obj = bpy.data.objects.new(\"TeapotSpout\", mesh)\nlink_obj(spout_obj)\nbpy.context.view_layer.objects.active = spout_obj\nbpy.ops.object.shade_smooth()\n\nmod = spout_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\nprint(\"Teapot spout built.\")\nresult = {\"spout_verts\": len(mesh.vertices)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:56:14.308055+00:00", "type": "tool_call", "id": "chatcmpl-tool-8655fd34dc5d3d15", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# TEAPOT SPOUT — curved tube\n# ============================================================\n# The spout rises from the lower body, curves outward and up\n\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\nspout_curve_data.dimensions = '3D'\nspout_curve_data.resolution_u = 16\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\n\nspline = spout_curve_data.splines.new('BEZIER')\n# Control points tracing the spout path (in body-local space)\n# Spout exits body around (0.85, 0, 0.25), curves up and out\nspout_points = [\n    (0.82, 0, 0.22),   # base at body\n    (1.05, 0, 0.30),   # curving out\n    (1.25, 0, 0.45),   # mid\n    (1.38, 0, 0.62),   # curving up\n    (1.42, 0, 0.80),   # near tip\n    (1.40, 0, 0.92),   # tip\n]\nspline.bezier_points.add(len(spout_points) - 1)\nfor i, pt in enumerate(spout_points):\n    bp = spline.bezier_points[i]\n    bp.co = pt\n    bp.handle_left_type = 'AUTO'\n    bp.handle_right_type = 'AUTO'\n\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\nlink_obj(spout_obj)\n\n# Convert curve to mesh, then taper it\nbpy.context.view_layer.objects.active = spout_obj\nbpy.ops.object.select_all(action='DESELECT')\nspout_obj.select_set(True)\nbpy.ops.object.convert(target='MESH')\n\nspout_mesh = spout_obj.data\n# Taper the spout: make it wider at base, narrower at tip\n# The mesh from curve conversion has vertices along the path\n# We'll scale based on z height\nmin_z = min(v.co.z for v in spout_mesh.vertices)\nmax_z = max(v.co.z for v in spout_mesh.vertices)\nz_range = max_z - min_z\n\nfor v in spout_mesh.vertices:\n    # normalize position along path (0=base, 1=tip)\n    t = (v.co.z - min_z) / max(z_range, 0.001)\n    # Radius taper: thick at base, narrow at tip\n    # Also widen the opening at the very tip (lip)\n    if t > 0.85:\n        # flare slightly at the spout lip\n        radius_factor = 0.12 + (t - 0.85) * 0.5\n    else:\n        radius_factor = 0.18 - t * 0.06\n    # Scale x,y around the path center (approximate by scaling from local axis)\n    # The spout extends along +x, so scale y and z-offset\n    center_x = 1.1  # approximate path center\n    v.co.y *= (radius_factor / 0.18)\n    v.co.z = v.co.z  # keep z\n\n# Actually, let me rebuild the spout more carefully with a proper tube\nbpy.data.objects.remove(spout_obj, do_unlink=True)\n\n# --- Rebuild spout as a proper tapered tube ---\nmesh = bpy.data.meshes.new(\"TeapotSpoutMesh\")\nbm = bmesh.new()\n\nsegments = 24\n# Spout centerline points\npath_points = [\n    Vector((0.80, 0, 0.20)),\n    Vector((1.00, 0, 0.26)),\n    Vector((1.20, 0, 0.38)),\n    Vector((1.34, 0, 0.55)),\n    Vector((1.40, 0, 0.74)),\n    Vector((1.38, 0, 0.90)),\n]\n# Radii at each point\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\n\n# Generate rings\nrings = []\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\n    ring = []\n    # Compute tangent (direction along path)\n    if pi == 0:\n        tangent = (path_points[1] - path_points[0]).normalized()\n    elif pi == len(path_points) - 1:\n        tangent = (path_points[-1] - path_points[-2]).normalized()\n    else:\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\n    \n    # Build a frame perpendicular to tangent\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\n    up = Vector((0, 0, 1))\n    if abs(tangent.dot(up)) > 0.9:\n        up = Vector((1, 0, 0))\n    right = tangent.cross(up).normalized()\n    up = right.cross(tangent).normalized()\n    \n    for i in range(segments):\n        angle = (i / segments) * math.tau\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\n        v = bm.verts.new(p + offset)\n        ring.append(v)\n    rings.append(ring)\n\nbm.verts.ensure_lookup_table()\n\n# Connect rings with faces\nfor ri in range(len(rings) - 1):\n    for i in range(segments):\n        j = (i + 1) % segments\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\n\n# Cap the tip (top) - the spout opening\ntip_ring = rings[-1]\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\n# Don't cap - leave open as a spout opening, but add a slight rim\n# Actually cap the base where it meets the body\nbase_ring = rings[0]\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\n# Leave both open for now (base merges into body)\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nspout_obj = bpy.data.objects.new(\"TeapotSpout\", mesh)\nlink_obj(spout_obj)\nbpy.context.view_layer.objects.active = spout_obj\nbpy.ops.object.shade_smooth()\n\nmod = spout_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\nprint(\"Teapot spout built.\")\nresult = {\"spout_verts\": len(mesh.vertices)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}
{"ts": "2026-07-17T14:56:15.381710+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:57:00.222621+00:00", "type": "llm_call", "call_index": 7, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:56:15.381710+00:00", "finished_at": "2026-07-17T14:57:00.221115+00:00", "duration_s": 44.84399999998277, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:56:15.381710+00:00", "finished_at": "2026-07-17T14:57:00.221115+00:00", "duration_s": 44.84399999998277, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "42443", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:56:28 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300187-527DoKvcx5WvvhhgkRNb", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca17e8de0d86a3-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300187-527DoKvcx5WvvhhgkRNb\",\"object\":\"chat.completion\",\"created\":1784300187,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":10283,\"completion_tokens\":1425,\"total_tokens\":11708,\"cost\":0.0072363054,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":8640,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0072363054,\"upstream_inference_prompt_cost\":0.0030416754,\"upstream_inference_completions_cost\":0.00419463},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDAxODctNTI3RG9LdmN4NVd2dmhoZ2tSTmIiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwMTg3LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYmM0ZWM0ZGRkM2U4MjYyNiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBIQU5ETEUg4oCUIGN1cnZlZCBoYW5kbGUgb24gdGhlIG9wcG9zaXRlIHNpZGUgZnJvbSBzcG91dFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEhhbmRsZU1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBIYW5kbGUgcGF0aDogc3RhcnRzIG9uIGJvZHkgdXBwZXItbGVmdCwgY3VydmVzIGRvd24gYW5kIGFyb3VuZCB0byBib2R5IGxvd2VyLWxlZnRcXG4jIEhhbmRsZSBpcyBvbiB0aGUgLXggc2lkZSAob3Bwb3NpdGUgdGhlIHNwb3V0KVxcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKC0wLjc4LCAwLCAwLjcyKSksICAgIyB0b3AgYXR0YWNobWVudFxcbiAgICBWZWN0b3IoKC0xLjA1LCAwLCAwLjY4KSksICAgIyB1cHBlciBjdXJ2ZSBvdXRcXG4gICAgVmVjdG9yKCgtMS4xOCwgMCwgMC41NSkpLCAgICMgb3V0ZXJcXG4gICAgVmVjdG9yKCgtMS4xNSwgMCwgMC4zOCkpLCAgICMgbWlkXFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuMjIpKSwgICAjIGxvd2VyIGN1cnZlIGluXFxuICAgIFZlY3RvcigoLTAuODIsIDAsIDAuMTgpKSwgICAjIGJvdHRvbSBhdHRhY2htZW50XFxuXVxcbnBhdGhfcmFkaWkgPSBbMC4wNywgMC4wOCwgMC4wODUsIDAuMDg1LCAwLjA4LCAwLjA3XVxcblxcbnJpbmdzID0gW11cXG5mb3IgcGksIChwLCByKSBpbiBlbnVtZXJhdGUoemlwKHBhdGhfcG9pbnRzLCBwYXRoX3JhZGlpKSk6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiBwaSA9PSAwOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1sxXSAtIHBhdGhfcG9pbnRzWzBdKS5ub3JtYWxpemVkKClcXG4gICAgZWxpZiBwaSA9PSBsZW4ocGF0aF9wb2ludHMpIC0gMTpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbLTFdIC0gcGF0aF9wb2ludHNbLTJdKS5ub3JtYWxpemVkKClcXG4gICAgZWxzZTpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbcGkrMV0gLSBwYXRoX3BvaW50c1twaS0xXSkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICB1cCA9IFZlY3RvcigoMCwgMCwgMSkpXFxuICAgIGlmIGFicyh0YW5nZW50LmRvdCh1cCkpID4gMC45OlxcbiAgICAgICAgdXAgPSBWZWN0b3IoKDEsIDAsIDApKVxcbiAgICByaWdodCA9IHRhbmdlbnQuY3Jvc3ModXApLm5vcm1hbGl6ZWQoKVxcbiAgICB1cCA9IHJpZ2h0LmNyb3NzKHRhbmdlbnQpLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICBvZmZzZXQgPSAobWF0aC5jb3MoYW5nbGUpICogcmlnaHQgKyBtYXRoLnNpbihhbmdsZSkgKiB1cCkgKiByXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KHAgKyBvZmZzZXQpXFxuICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICByaW5ncy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5oYW5kbGVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEhhbmRsZVxcXCIsIG1lc2gpXFxubGlua19vYmooaGFuZGxlX29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gaGFuZGxlX29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxubW9kID0gaGFuZGxlX29iai5tb2RpZmllcnMubmV3KFxcXCJTdWJzdXJmXFxcIiwgJ1NVQlNVUkYnKVxcbm1vZC5sZXZlbHMgPSAxXFxubW9kLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBMSUQg4oCUIGRvbWUgd2l0aCBrbm9iXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90TGlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgTGlkIHByb2ZpbGU6IHNpdHMgb24gdGhlIG5lY2ssIGRvbWVzIHVwLCBoYXMgYSBrbm9iXFxubGlkX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjk4KSwgICAjIGNlbnRlclxcbiAgICAoMC4zMCwgMC45OCksICAgIyBzZWF0IGVkZ2UgKG1hdGNoZXMgbmVjayB0b3ApXFxuICAgICgwLjMwLCAxLjAwKSwgICAjIGxpcCB1cFxcbiAgICAoMC4yOCwgMS4wMiksICAgIyBcXG4gICAgKDAuMjQsIDEuMDYpLCAgICMgZG9tZVxcbiAgICAoMC4xOCwgMS4xMCksICAgIyBcXG4gICAgKDAuMTIsIDEuMTMpLCAgICMgXFxuICAgICgwLjA3LCAxLjE1KSwgICAjIGtub2IgYmFzZVxcbiAgICAoMC4wNSwgMS4xNyksICAgIyBcXG4gICAgKDAuMDQsIDEuMTkpLCAgICMga25vYiB0b3BcXG4gICAgKDAuMDAsIDEuMTkpLCAgICMga25vYiBjYXBcXG5dXFxuXFxuc2VnbWVudHMgPSA0OFxcbmFsbF92ZXJ0cyA9IFtdXFxuZm9yIHIsIGggaW4gbGlkX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBsaWRfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBsaWRfcHJvZmlsZVtyaSArIDFdXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGlmIHJhIDwgMC4wMDE6XFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmxpZF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90TGlkXFxcIiwgbWVzaClcXG5saW5rX29iaihsaWRfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBsaWRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBsaWRfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG4jIFBhcmVudCBhbGwgdGVhcG90IHBhcnRzIHRvIGFuIGVtcHR5IGZvciBlYXN5IHBvc2l0aW9uaW5nXFxuYnB5Lm9wcy5vYmplY3QuZW1wdHlfYWRkKHR5cGU9J1BMQUlOX0FYRVMnLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxudGVhcG90X2VtcHR5ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnRlYXBvdF9lbXB0eS5uYW1lID0gXFxcIlV0YWhUZWFwb3RcXFwiXFxudGVhcG90X2VtcHR5LmVtcHR5X2Rpc3BsYXlfc2l6ZSA9IDAuNVxcblxcbmZvciBuYW1lIGluIFtcXFwiVGVhcG90Qm9keVxcXCIsIFxcXCJUZWFwb3RTcG91dFxcXCIsIFxcXCJUZWFwb3RIYW5kbGVcXFwiLCBcXFwiVGVhcG90TGlkXFxcIl06XFxuICAgIG9iaiA9IGJweS5kYXRhLm9iamVjdHNbbmFtZV1cXG4gICAgb2JqLnBhcmVudCA9IHRlYXBvdF9lbXB0eVxcbiAgICBvYmoubWF0cml4X3BhcmVudF9pbnZlcnNlID0gdGVhcG90X2VtcHR5Lm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBoYW5kbGUsIGxpZCBidWlsdCBhbmQgcGFyZW50ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInRlYXBvdF9wYXJ0c1xcXCI6IFtcXFwiVGVhcG90Qm9keVxcXCIsIFxcXCJUZWFwb3RTcG91dFxcXCIsIFxcXCJUZWFwb3RIYW5kbGVcXFwiLCBcXFwiVGVhcG90TGlkXFxcIl19XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MTAyODMsImNvbXBsZXRpb25fdG9rZW5zIjoxNDI1LCJ0b3RhbF90b2tlbnMiOjExNzA4LCJjb3N0IjowLjAwNzIzNjMwNTQsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6ODY0MCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDcyMzYzMDU0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDAzMDQxNjc1NCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDA0MTk0NjN9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# TEAPOT HANDLE — curved handle on the opposite side from spout\n# ============================================================\nmesh = bpy.data.meshes.new(\"TeapotHandleMesh\")\nbm = bmesh.new()\n\nsegments = 24\n# Handle path: starts on body upper-left, curves down and around to body lower-left\n# Handle is on the -x side (opposite the spout)\npath_points = [\n    Vector((-0.78, 0, 0.72)),   # top attachment\n    Vector((-1.05, 0, 0.68)),   # upper curve out\n    Vector((-1.18, 0, 0.55)),   # outer\n    Vector((-1.15, 0, 0.38)),   # mid\n    Vector((-1.05, 0, 0.22)),   # lower curve in\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\n]\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\n\nrings = []\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\n    ring = []\n    if pi == 0:\n        tangent = (path_points[1] - path_points[0]).normalized()\n    elif pi == len(path_points) - 1:\n        tangent = (path_points[-1] - path_points[-2]).normalized()\n    else:\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\n    \n    up = Vector((0, 0, 1))\n    if abs(tangent.dot(up)) > 0.9:\n        up = Vector((1, 0, 0))\n    right = tangent.cross(up).normalized()\n    up = right.cross(tangent).normalized()\n    \n    for i in range(segments):\n        angle = (i / segments) * math.tau\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\n        v = bm.verts.new(p + offset)\n        ring.append(v)\n    rings.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(rings) - 1):\n    for i in range(segments):\n        j = (i + 1) % segments\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nhandle_obj = bpy.data.objects.new(\"TeapotHandle\", mesh)\nlink_obj(handle_obj)\nbpy.context.view_layer.objects.active = handle_obj\nbpy.ops.object.shade_smooth()\n\nmod = handle_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\n# ============================================================\n# TEAPOT LID — dome with knob\n# ============================================================\nmesh = bpy.data.meshes.new(\"TeapotLidMesh\")\nbm = bmesh.new()\n\n# Lid profile: sits on the neck, domes up, has a knob\nlid_profile = [\n    (0.00, 0.98),   # center\n    (0.30, 0.98),   # seat edge (matches neck top)\n    (0.30, 1.00),   # lip up\n    (0.28, 1.02),   # \n    (0.24, 1.06),   # dome\n    (0.18, 1.10),   # \n    (0.12, 1.13),   # \n    (0.07, 1.15),   # knob base\n    (0.05, 1.17),   # \n    (0.04, 1.19),   # knob top\n    (0.00, 1.19),   # knob cap\n]\n\nsegments = 48\nall_verts = []\nfor r, h in lid_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = lid_profile[ri]\n    rb, _ = lid_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nlid_obj = bpy.data.objects.new(\"TeapotLid\", mesh)\nlink_obj(lid_obj)\nbpy.context.view_layer.objects.active = lid_obj\nbpy.ops.object.shade_smooth()\n\nmod = lid_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 2\nmod.render_levels = 3\n\n# Parent all teapot parts to an empty for easy positioning\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\nteapot_empty = bpy.context.active_object\nteapot_empty.name = \"UtahTeapot\"\nteapot_empty.empty_display_size = 0.5\n\nfor name in [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]:\n    obj = bpy.data.objects[name]\n    obj.parent = teapot_empty\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\n\nprint(\"Teapot handle, lid built and parented.\")\nresult = {\"teapot_parts\": [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}", "parse_error": null}], "tokens_in": 10283, "tokens_out": 1425, "cost_usd": 0.0072363054, "cached_tokens": 8640}, "error": null}
{"ts": "2026-07-17T14:57:00.224636+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# TEAPOT HANDLE — curved handle on the opposite side from spout\n# ============================================================\nmesh = bpy.data.meshes.new(\"TeapotHandleMesh\")\nbm = bmesh.new()\n\nsegments = 24\n# Handle path: starts on body upper-left, curves down and around to body lower-left\n# Handle is on the -x side (opposite the spout)\npath_points = [\n    Vector((-0.78, 0, 0.72)),   # top attachment\n    Vector((-1.05, 0, 0.68)),   # upper curve out\n    Vector((-1.18, 0, 0.55)),   # outer\n    Vector((-1.15, 0, 0.38)),   # mid\n    Vector((-1.05, 0, 0.22)),   # lower curve in\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\n]\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\n\nrings = []\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\n    ring = []\n    if pi == 0:\n        tangent = (path_points[1] - path_points[0]).normalized()\n    elif pi == len(path_points) - 1:\n        tangent = (path_points[-1] - path_points[-2]).normalized()\n    else:\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\n    \n    up = Vector((0, 0, 1))\n    if abs(tangent.dot(up)) > 0.9:\n        up = Vector((1, 0, 0))\n    right = tangent.cross(up).normalized()\n    up = right.cross(tangent).normalized()\n    \n    for i in range(segments):\n        angle = (i / segments) * math.tau\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\n        v = bm.verts.new(p + offset)\n        ring.append(v)\n    rings.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(rings) - 1):\n    for i in range(segments):\n        j = (i + 1) % segments\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nhandle_obj = bpy.data.objects.new(\"TeapotHandle\", mesh)\nlink_obj(handle_obj)\nbpy.context.view_layer.objects.active = handle_obj\nbpy.ops.object.shade_smooth()\n\nmod = handle_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\n# ============================================================\n# TEAPOT LID — dome with knob\n# ============================================================\nmesh = bpy.data.meshes.new(\"TeapotLidMesh\")\nbm = bmesh.new()\n\n# Lid profile: sits on the neck, domes up, has a knob\nlid_profile = [\n    (0.00, 0.98),   # center\n    (0.30, 0.98),   # seat edge (matches neck top)\n    (0.30, 1.00),   # lip up\n    (0.28, 1.02),   # \n    (0.24, 1.06),   # dome\n    (0.18, 1.10),   # \n    (0.12, 1.13),   # \n    (0.07, 1.15),   # knob base\n    (0.05, 1.17),   # \n    (0.04, 1.19),   # knob top\n    (0.00, 1.19),   # knob cap\n]\n\nsegments = 48\nall_verts = []\nfor r, h in lid_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = lid_profile[ri]\n    rb, _ = lid_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nlid_obj = bpy.data.objects.new(\"TeapotLid\", mesh)\nlink_obj(lid_obj)\nbpy.context.view_layer.objects.active = lid_obj\nbpy.ops.object.shade_smooth()\n\nmod = lid_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 2\nmod.render_levels = 3\n\n# Parent all teapot parts to an empty for easy positioning\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\nteapot_empty = bpy.context.active_object\nteapot_empty.name = \"UtahTeapot\"\nteapot_empty.empty_display_size = 0.5\n\nfor name in [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]:\n    obj = bpy.data.objects[name]\n    obj.parent = teapot_empty\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\n\nprint(\"Teapot handle, lid built and parented.\")\nresult = {\"teapot_parts\": [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:57:00.224636+00:00", "type": "tool_call", "id": "chatcmpl-tool-bc4ec4ddd3e82626", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# TEAPOT HANDLE — curved handle on the opposite side from spout\n# ============================================================\nmesh = bpy.data.meshes.new(\"TeapotHandleMesh\")\nbm = bmesh.new()\n\nsegments = 24\n# Handle path: starts on body upper-left, curves down and around to body lower-left\n# Handle is on the -x side (opposite the spout)\npath_points = [\n    Vector((-0.78, 0, 0.72)),   # top attachment\n    Vector((-1.05, 0, 0.68)),   # upper curve out\n    Vector((-1.18, 0, 0.55)),   # outer\n    Vector((-1.15, 0, 0.38)),   # mid\n    Vector((-1.05, 0, 0.22)),   # lower curve in\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\n]\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\n\nrings = []\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\n    ring = []\n    if pi == 0:\n        tangent = (path_points[1] - path_points[0]).normalized()\n    elif pi == len(path_points) - 1:\n        tangent = (path_points[-1] - path_points[-2]).normalized()\n    else:\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\n    \n    up = Vector((0, 0, 1))\n    if abs(tangent.dot(up)) > 0.9:\n        up = Vector((1, 0, 0))\n    right = tangent.cross(up).normalized()\n    up = right.cross(tangent).normalized()\n    \n    for i in range(segments):\n        angle = (i / segments) * math.tau\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\n        v = bm.verts.new(p + offset)\n        ring.append(v)\n    rings.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(rings) - 1):\n    for i in range(segments):\n        j = (i + 1) % segments\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nhandle_obj = bpy.data.objects.new(\"TeapotHandle\", mesh)\nlink_obj(handle_obj)\nbpy.context.view_layer.objects.active = handle_obj\nbpy.ops.object.shade_smooth()\n\nmod = handle_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\n# ============================================================\n# TEAPOT LID — dome with knob\n# ============================================================\nmesh = bpy.data.meshes.new(\"TeapotLidMesh\")\nbm = bmesh.new()\n\n# Lid profile: sits on the neck, domes up, has a knob\nlid_profile = [\n    (0.00, 0.98),   # center\n    (0.30, 0.98),   # seat edge (matches neck top)\n    (0.30, 1.00),   # lip up\n    (0.28, 1.02),   # \n    (0.24, 1.06),   # dome\n    (0.18, 1.10),   # \n    (0.12, 1.13),   # \n    (0.07, 1.15),   # knob base\n    (0.05, 1.17),   # \n    (0.04, 1.19),   # knob top\n    (0.00, 1.19),   # knob cap\n]\n\nsegments = 48\nall_verts = []\nfor r, h in lid_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = lid_profile[ri]\n    rb, _ = lid_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nlid_obj = bpy.data.objects.new(\"TeapotLid\", mesh)\nlink_obj(lid_obj)\nbpy.context.view_layer.objects.active = lid_obj\nbpy.ops.object.shade_smooth()\n\nmod = lid_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 2\nmod.render_levels = 3\n\n# Parent all teapot parts to an empty for easy positioning\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\nteapot_empty = bpy.context.active_object\nteapot_empty.name = \"UtahTeapot\"\nteapot_empty.empty_display_size = 0.5\n\nfor name in [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]:\n    obj = bpy.data.objects[name]\n    obj.parent = teapot_empty\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\n\nprint(\"Teapot handle, lid built and parented.\")\nresult = {\"teapot_parts\": [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}
{"ts": "2026-07-17T14:57:01.847772+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:57:52.538011+00:00", "type": "llm_call", "call_index": 8, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:57:01.847772+00:00", "finished_at": "2026-07-17T14:57:52.537010+00:00", "duration_s": 50.687000000005355, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:57:01.847772+00:00", "finished_at": "2026-07-17T14:57:52.537010+00:00", "duration_s": 50.687000000005355, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "47911", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:57:12 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300222-Cz9H3rpHXSi90dnPtqev", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca18c60fa24a2c-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300222-Cz9H3rpHXSi90dnPtqev\",\"object\":\"chat.completion\",\"created\":1784300222,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":11780,\"completion_tokens\":1384,\"total_tokens\":13164,\"cost\":0.007297452,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":10240,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.007297452,\"upstream_inference_prompt_cost\":0.0032235096,\"upstream_inference_completions_cost\":0.0040739424},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMDIyMi1DejlIM3JwSFhTaTkwZG5QdHFldiIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDAyMjIsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIHRoZSBTdGFuZm9yZCBCdW5ueSDigJQgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gd2l0aCB0aGUgY29tcGFjdCBjcm91Y2hlZCBzaWxob3VldHRlLiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC05ZDk1OGQxZGJkMGYyYmM0IiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgU1RBTkZPUkQgQlVOTlkg4oCUIGNvbXBhY3QgY3JvdWNoZWQtcmFiYml0IHNpbGhvdWV0dGVcXG4jIEJ1aWx0IGZyb20gbWV0YWJhbGxzIC8gc2hhcGVkIHNwaGVyZXMgZm9yIHRoZSByb3VuZGVkIG9yZ2FuaWMgZm9ybVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBVc2UgYSBiYXNlIG1lc2ggYW5kIHNoYXBlIGl0IHdpdGggcHJvcG9ydGlvbmFsIGVkaXRpbmctbGlrZSB2ZXJ0ZXggbWF0aFxcbiMgU3RhcnQgd2l0aCBhIFVWIHNwaGVyZSBhbmQgc2N1bHB0IHRoZSBidW5ueSBmb3JtXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkJ1bm55TWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIHRoZSBidW5ueSBib2R5IGFzIGEgc2VyaWVzIG9mIG1lcmdlZCBzcGhlcmVzXFxuIyBUaGlzIGlzIGEgc2N1bHB0dXJhbCBhcHByb3hpbWF0aW9uIC0gY3JvdWNoZWQgcmFiYml0LCByb3VuZGVkIGJhY2ssIGZvbGRlZCBlYXJzXFxuXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz0wLjMsIHNlZ21lbnRzPTQ4LCByaW5nX2NvdW50PTI0LCBsb2NhdGlvbj0oMCwwLDApKVxcbmJvZHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYm9keS5uYW1lID0gXFxcIkJ1bm55Qm9keVRlbXBcXFwiXFxuXFxuIyBXZSdsbCBidWlsZCB0aGUgYnVubnkgZnJvbSBtdWx0aXBsZSBtZXRhYmFsbC1saWtlIHNwaGVyZSBwYXJ0cyBtZXJnZWRcXG4jIEJvZHkgcGFydHMgKGluIGxvY2FsIHNwYWNlLCB3aWxsIGJlIHBvc2l0aW9uZWQgbGF0ZXIpOlxcbnBhcnRzID0gW11cXG5cXG5kZWYgYWRkX3NwaGVyZV9wYXJ0KGJtLCBjZW50ZXIsIHJhZGl1cywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEsMSwxKSk6XFxuICAgIFxcXCJcXFwiXFxcIkFkZCBhIHNwaGVyZSBvZiB2ZXJ0aWNlcyB0byBibWVzaCwgcmV0dXJucyB0aGUgcmluZyBzdHJ1Y3R1cmUuXFxcIlxcXCJcXFwiXFxuICAgIHZlcnRzX2dyaWQgPSBbXVxcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MgKyAxKTpcXG4gICAgICAgIHBoaSA9IG1hdGgucGkgKiByaSAvIHJpbmdzICAjIDAgdG8gcGlcXG4gICAgICAgIHJpbmcgPSBbXVxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICB0aGV0YSA9IG1hdGgudGF1ICogc2kgLyBzZWdtZW50c1xcbiAgICAgICAgICAgIHggPSByYWRpdXMgKiBtYXRoLnNpbihwaGkpICogbWF0aC5jb3ModGhldGEpICogc3F1YXNoWzBdXFxuICAgICAgICAgICAgeSA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLnNpbih0aGV0YSkgKiBzcXVhc2hbMV1cXG4gICAgICAgICAgICB6ID0gcmFkaXVzICogbWF0aC5jb3MocGhpKSAqIHNxdWFzaFsyXVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKGNlbnRlclswXSArIHgsIGNlbnRlclsxXSArIHksIGNlbnRlclsyXSArIHopKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgICAgICB2ZXJ0c19ncmlkLmFwcGVuZChyaW5nKVxcbiAgICBcXG4gICAgIyBDcmVhdGUgZmFjZXNcXG4gICAgZm9yIHJpIGluIHJhbmdlKHJpbmdzKTpcXG4gICAgICAgIGZvciBzaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgc2ogPSAoc2kgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICAgICAgdHJ5OlxcbiAgICAgICAgICAgICAgICBibS5mYWNlcy5uZXcoW3ZlcnRzX2dyaWRbcmldW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzaV0sIHZlcnRzX2dyaWRbcmkrMV1bc2pdLCB2ZXJ0c19ncmlkW3JpXVtzal1dKVxcbiAgICAgICAgICAgIGV4Y2VwdDpcXG4gICAgICAgICAgICAgICAgcGFzc1xcbiAgICByZXR1cm4gdmVydHNfZ3JpZFxcblxcbiMgRGVsZXRlIHRlbXAgb2JqZWN0XFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoYm9keSwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBCdWlsZCBidW5ueSBhcyBhIHVuaW9uIG9mIHNxdWFzaGVkIHNwaGVyZXNcXG4jIFRoZSBTdGFuZm9yZCBidW5ueSBzaXRzIGNyb3VjaGVkLCBmYWNpbmcgZm9yd2FyZCwgd2l0aCBhIHJvdW5kZWQgYmFja1xcbiMgS2V5IGZlYXR1cmVzOiByb3VuZGVkIGJvZHkgbWFzcywgaGVhZCB0dWNrZWQgZm9yd2FyZCwgZm9sZGVkIGVhcnMgYWxvbmcgYmFja1xcblxcbiMgTWFpbiBib2R5IG1hc3MgKGxhcmdlLCBlbG9uZ2F0ZWQsIGNyb3VjaGVkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAsIDAsIDAuMTgpLCAwLjI4LCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMS40LCAwLjksIDAuODUpKVxcbiMgTG93ZXIgYm9keSAvIGhhdW5jaGVzXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4wNSksIDAuMjIsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjMsIDAuOTUsIDAuNikpXFxuIyBIZWFkIChmb3J3YXJkIGFuZCBzbGlnaHRseSBkb3duKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMzIsIDAsIDAuMjgpLCAwLjE2LCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMS4xLCAwLjksIDAuOTUpKVxcbiMgTm9zZSBhcmVhXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC40NCwgMCwgMC4yNCksIDAuMDcsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjAsIDAuOCwgMC44KSlcXG5cXG4jIEVhcnMgKGZvbGRlZCBiYWNrIGFsb25nIHRoZSBib2R5KSAtIHR3byBmbGF0dGVuZWQgZWxvbmdhdGVkIGZvcm1zXFxuIyBMZWZ0IGVhclxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMDUsIDAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG4jIFJpZ2h0IGVhclxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMDUsIC0wLjEwLCAwLjQ2KSwgMC4xMCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDAuMzUsIDAuMjUsIDEuNikpXFxuXFxuIyBGcm9udCBsZWdzL3Bhd3MgKGZvbGRlZCB1bmRlcilcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAwLjA1LCAwLjApLCAwLjA4LCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMS4yLCAwLjYsIDAuNCkpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4yNSwgLTAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5cXG4jIEJhY2sgaGF1bmNoZXMgKHJhaXNlZClcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgtMC4xNSwgMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgtMC4xNSwgLTAuMTIsIDAuMTIpLCAwLjE0LCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMS4wLCAwLjgsIDEuMSkpXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJ1bm55X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJTdGFuZm9yZEJ1bm55XFxcIiwgbWVzaClcXG5saW5rX29iaihidW5ueV9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1bm55X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgcmVtZXNoIG1vZGlmaWVyIHRvIHVuaWZ5IHRoZSBzZXBhcmF0ZSBzcGhlcmVzIGludG8gYSBzbW9vdGggc3VyZmFjZVxcbiMgVXNlIGEgcmVtZXNoIHRvIGJsZW5kIHRoZSBwYXJ0c1xcbnJlbWVzaCA9IGJ1bm55X29iai5tb2RpZmllcnMubmV3KFxcXCJSZW1lc2hcXFwiLCAnUkVNRVNIJylcXG5yZW1lc2gubW9kZSA9ICdTTU9PVEgnXFxucmVtZXNoLnZveGVsX3NpemUgPSAwLjAzXFxucmVtZXNoLmFkYXB0aXZpdHkgPSAwLjAwMlxcblxcbiMgQWRkIHN1YnN1cmYgYWZ0ZXIgcmVtZXNoIGZvciBleHRyYSBzbW9vdGhuZXNzXFxuc3Vic3VyZiA9IGJ1bm55X29iai5tb2RpZmllcnMubmV3KFxcXCJTdWJzdXJmXFxcIiwgJ1NVQlNVUkYnKVxcbnN1YnN1cmYubGV2ZWxzID0gMVxcbnN1YnN1cmYucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jIFNjYWxlIHRvIHNpdCBvbiB0YWJsZSBhdCByZWFzb25hYmxlIHNpemVcXG5idW5ueV9vYmouc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG5wcmludChcXFwiU3RhbmZvcmQgQnVubnkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImJ1bm55X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjExNzgwLCJjb21wbGV0aW9uX3Rva2VucyI6MTM4NCwidG90YWxfdG9rZW5zIjoxMzE2NCwiY29zdCI6MC4wMDcyOTc0NTIsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MTAyNDAsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA3Mjk3NDUyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDAzMjIzNTA5NiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDA0MDczOTQyNH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# STANFORD BUNNY — compact crouched-rabbit silhouette\n# Built from metaballs / shaped spheres for the rounded organic form\n# ============================================================\n\n# Use a base mesh and shape it with proportional editing-like vertex math\n# Start with a UV sphere and sculpt the bunny form\n\nmesh = bpy.data.meshes.new(\"BunnyMesh\")\nbm = bmesh.new()\n\n# Create the bunny body as a series of merged spheres\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\n\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\nbody = bpy.context.active_object\nbody.name = \"BunnyBodyTemp\"\n\n# We'll build the bunny from multiple metaball-like sphere parts merged\n# Body parts (in local space, will be positioned later):\nparts = []\n\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\n    \"\"\"Add a sphere of vertices to bmesh, returns the ring structure.\"\"\"\n    verts_grid = []\n    for ri in range(rings + 1):\n        phi = math.pi * ri / rings  # 0 to pi\n        ring = []\n        for si in range(segments):\n            theta = math.tau * si / segments\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\n            z = radius * math.cos(phi) * squash[2]\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\n            ring.append(v)\n        verts_grid.append(ring)\n    \n    # Create faces\n    for ri in range(rings):\n        for si in range(segments):\n            sj = (si + 1) % segments\n            try:\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\n            except:\n                pass\n    return verts_grid\n\n# Delete temp object\nbpy.data.objects.remove(body, do_unlink=True)\n\n# Build bunny as a union of squashed spheres\n# The Stanford bunny sits crouched, facing forward, with a rounded back\n# Key features: rounded body mass, head tucked forward, folded ears along back\n\n# Main body mass (large, elongated, crouched)\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\n# Lower body / haunches\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\n# Head (forward and slightly down)\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\n# Nose area\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\n\n# Ears (folded back along the body) - two flattened elongated forms\n# Left ear\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\n# Right ear\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\n\n# Front legs/paws (folded under)\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\n\n# Back haunches (raised)\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nbunny_obj = bpy.data.objects.new(\"StanfordBunny\", mesh)\nlink_obj(bunny_obj)\nbpy.context.view_layer.objects.active = bunny_obj\nbpy.ops.object.shade_smooth()\n\n# Add remesh modifier to unify the separate spheres into a smooth surface\n# Use a remesh to blend the parts\nremesh = bunny_obj.modifiers.new(\"Remesh\", 'REMESH')\nremesh.mode = 'SMOOTH'\nremesh.voxel_size = 0.03\nremesh.adaptivity = 0.002\n\n# Add subsurf after remesh for extra smoothness\nsubsurf = bunny_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nsubsurf.levels = 1\nsubsurf.render_levels = 2\n\n# Scale to sit on table at reasonable size\nbunny_obj.scale = (1.0, 1.0, 1.0)\n\nprint(\"Stanford Bunny built.\")\nresult = {\"bunny_verts\": len(mesh.vertices)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}", "parse_error": null}], "tokens_in": 11780, "tokens_out": 1384, "cost_usd": 0.007297452, "cached_tokens": 10240}, "error": null}
{"ts": "2026-07-17T14:57:52.539010+00:00", "type": "assistant", "text": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# STANFORD BUNNY — compact crouched-rabbit silhouette\n# Built from metaballs / shaped spheres for the rounded organic form\n# ============================================================\n\n# Use a base mesh and shape it with proportional editing-like vertex math\n# Start with a UV sphere and sculpt the bunny form\n\nmesh = bpy.data.meshes.new(\"BunnyMesh\")\nbm = bmesh.new()\n\n# Create the bunny body as a series of merged spheres\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\n\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\nbody = bpy.context.active_object\nbody.name = \"BunnyBodyTemp\"\n\n# We'll build the bunny from multiple metaball-like sphere parts merged\n# Body parts (in local space, will be positioned later):\nparts = []\n\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\n    \"\"\"Add a sphere of vertices to bmesh, returns the ring structure.\"\"\"\n    verts_grid = []\n    for ri in range(rings + 1):\n        phi = math.pi * ri / rings  # 0 to pi\n        ring = []\n        for si in range(segments):\n            theta = math.tau * si / segments\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\n            z = radius * math.cos(phi) * squash[2]\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\n            ring.append(v)\n        verts_grid.append(ring)\n    \n    # Create faces\n    for ri in range(rings):\n        for si in range(segments):\n            sj = (si + 1) % segments\n            try:\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\n            except:\n                pass\n    return verts_grid\n\n# Delete temp object\nbpy.data.objects.remove(body, do_unlink=True)\n\n# Build bunny as a union of squashed spheres\n# The Stanford bunny sits crouched, facing forward, with a rounded back\n# Key features: rounded body mass, head tucked forward, folded ears along back\n\n# Main body mass (large, elongated, crouched)\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\n# Lower body / haunches\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\n# Head (forward and slightly down)\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\n# Nose area\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\n\n# Ears (folded back along the body) - two flattened elongated forms\n# Left ear\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\n# Right ear\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\n\n# Front legs/paws (folded under)\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\n\n# Back haunches (raised)\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nbunny_obj = bpy.data.objects.new(\"StanfordBunny\", mesh)\nlink_obj(bunny_obj)\nbpy.context.view_layer.objects.active = bunny_obj\nbpy.ops.object.shade_smooth()\n\n# Add remesh modifier to unify the separate spheres into a smooth surface\n# Use a remesh to blend the parts\nremesh = bunny_obj.modifiers.new(\"Remesh\", 'REMESH')\nremesh.mode = 'SMOOTH'\nremesh.voxel_size = 0.03\nremesh.adaptivity = 0.002\n\n# Add subsurf after remesh for extra smoothness\nsubsurf = bunny_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nsubsurf.levels = 1\nsubsurf.render_levels = 2\n\n# Scale to sit on table at reasonable size\nbunny_obj.scale = (1.0, 1.0, 1.0)\n\nprint(\"Stanford Bunny built.\")\nresult = {\"bunny_verts\": len(mesh.vertices)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:57:52.539010+00:00", "type": "tool_call", "id": "chatcmpl-tool-9d958d1dbd0f2bc4", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# STANFORD BUNNY — compact crouched-rabbit silhouette\n# Built from metaballs / shaped spheres for the rounded organic form\n# ============================================================\n\n# Use a base mesh and shape it with proportional editing-like vertex math\n# Start with a UV sphere and sculpt the bunny form\n\nmesh = bpy.data.meshes.new(\"BunnyMesh\")\nbm = bmesh.new()\n\n# Create the bunny body as a series of merged spheres\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\n\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\nbody = bpy.context.active_object\nbody.name = \"BunnyBodyTemp\"\n\n# We'll build the bunny from multiple metaball-like sphere parts merged\n# Body parts (in local space, will be positioned later):\nparts = []\n\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\n    \"\"\"Add a sphere of vertices to bmesh, returns the ring structure.\"\"\"\n    verts_grid = []\n    for ri in range(rings + 1):\n        phi = math.pi * ri / rings  # 0 to pi\n        ring = []\n        for si in range(segments):\n            theta = math.tau * si / segments\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\n            z = radius * math.cos(phi) * squash[2]\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\n            ring.append(v)\n        verts_grid.append(ring)\n    \n    # Create faces\n    for ri in range(rings):\n        for si in range(segments):\n            sj = (si + 1) % segments\n            try:\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\n            except:\n                pass\n    return verts_grid\n\n# Delete temp object\nbpy.data.objects.remove(body, do_unlink=True)\n\n# Build bunny as a union of squashed spheres\n# The Stanford bunny sits crouched, facing forward, with a rounded back\n# Key features: rounded body mass, head tucked forward, folded ears along back\n\n# Main body mass (large, elongated, crouched)\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\n# Lower body / haunches\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\n# Head (forward and slightly down)\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\n# Nose area\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\n\n# Ears (folded back along the body) - two flattened elongated forms\n# Left ear\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\n# Right ear\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\n\n# Front legs/paws (folded under)\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\n\n# Back haunches (raised)\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nbunny_obj = bpy.data.objects.new(\"StanfordBunny\", mesh)\nlink_obj(bunny_obj)\nbpy.context.view_layer.objects.active = bunny_obj\nbpy.ops.object.shade_smooth()\n\n# Add remesh modifier to unify the separate spheres into a smooth surface\n# Use a remesh to blend the parts\nremesh = bunny_obj.modifiers.new(\"Remesh\", 'REMESH')\nremesh.mode = 'SMOOTH'\nremesh.voxel_size = 0.03\nremesh.adaptivity = 0.002\n\n# Add subsurf after remesh for extra smoothness\nsubsurf = bunny_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nsubsurf.levels = 1\nsubsurf.render_levels = 2\n\n# Scale to sit on table at reasonable size\nbunny_obj.scale = (1.0, 1.0, 1.0)\n\nprint(\"Stanford Bunny built.\")\nresult = {\"bunny_verts\": len(mesh.vertices)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}
{"ts": "2026-07-17T14:57:54.389126+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:58:08.426528+00:00", "type": "llm_call", "call_index": 9, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:57:54.390123+00:00", "finished_at": "2026-07-17T14:58:08.426528+00:00", "duration_s": 14.03100000001723, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:57:54.390123+00:00", "finished_at": "2026-07-17T14:58:08.426528+00:00", "duration_s": 14.03100000001723, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "52907", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:57:56 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300275-FoMYS3uRq75UIo9wxYEI", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1a0e7873f059-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300275-FoMYS3uRq75UIo9wxYEI\",\"object\":\"chat.completion\",\"created\":1784300275,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":13206,\"completion_tokens\":494,\"total_tokens\":13700,\"cost\":0.00484179384,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":11776,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00484179384,\"upstream_inference_prompt_cost\":0.00338765544,\"upstream_inference_completions_cost\":0.0014541384},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMDI3NS1Gb01ZUzN1UnE3NVVJbzl3eFlFSSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDAyNzUsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjEzMjA2LCJjb21wbGV0aW9uX3Rva2VucyI6NDk0LCJ0b3RhbF90b2tlbnMiOjEzNzAwLCJjb3N0IjowLjAwNDg0MTc5Mzg0LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjExNzc2LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwNDg0MTc5Mzg0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDAzMzg3NjU1NDQsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMTQ1NDEzODR9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\n# ============================================================\n# SUZANNE — Blender's monkey head, as a bust\n# ============================================================\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\nsuzanne = bpy.context.active_object\nsuzanne.name = \"Suzanne\"\n\n# Add a simple bust base/pedestal under Suzanne\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\nbust_base = bpy.context.active_object\nbust_base.name = \"SuzanneBase\"\nbpy.ops.object.shade_smooth()\n\n# Taper the base slightly (classical bust pedestal)\nbpy.context.view_layer.objects.active = bust_base\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=3)\nbpy.ops.object.mode_set(mode='OBJECT')\n# Scale top vertices slightly\nmesh = bust_base.data\nfor v in mesh.vertices:\n    if v.co.z > 0.04:\n        v.co.x *= 0.7\n        v.co.y *= 0.7\n\n# Parent base to Suzanne for now\nbust_base.parent = suzanne\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\n\nprint(\"Suzanne and bust base built.\")\n\n# ============================================================\n# CHECKERED SPHERE — ray-tracing demo classic\n# ============================================================\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\nsphere = bpy.context.active_object\nsphere.name = \"CheckeredSphere\"\nbpy.ops.object.shade_smooth()\n\n# Add subsurf for perfectly smooth sphere\nmod = sphere.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\nprint(\"Checkered sphere built.\")\nresult = {\"suzanne_verts\": len(suzanne.data.vertices), \"sphere_verts\": len(sphere.data.vertices)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}", "parse_error": null}], "tokens_in": 13206, "tokens_out": 494, "cost_usd": 0.00484179384, "cached_tokens": 11776}, "error": null}
{"ts": "2026-07-17T14:58:08.428528+00:00", "type": "assistant", "text": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\n# ============================================================\n# SUZANNE — Blender's monkey head, as a bust\n# ============================================================\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\nsuzanne = bpy.context.active_object\nsuzanne.name = \"Suzanne\"\n\n# Add a simple bust base/pedestal under Suzanne\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\nbust_base = bpy.context.active_object\nbust_base.name = \"SuzanneBase\"\nbpy.ops.object.shade_smooth()\n\n# Taper the base slightly (classical bust pedestal)\nbpy.context.view_layer.objects.active = bust_base\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=3)\nbpy.ops.object.mode_set(mode='OBJECT')\n# Scale top vertices slightly\nmesh = bust_base.data\nfor v in mesh.vertices:\n    if v.co.z > 0.04:\n        v.co.x *= 0.7\n        v.co.y *= 0.7\n\n# Parent base to Suzanne for now\nbust_base.parent = suzanne\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\n\nprint(\"Suzanne and bust base built.\")\n\n# ============================================================\n# CHECKERED SPHERE — ray-tracing demo classic\n# ============================================================\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\nsphere = bpy.context.active_object\nsphere.name = \"CheckeredSphere\"\nbpy.ops.object.shade_smooth()\n\n# Add subsurf for perfectly smooth sphere\nmod = sphere.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\nprint(\"Checkered sphere built.\")\nresult = {\"suzanne_verts\": len(suzanne.data.vertices), \"sphere_verts\": len(sphere.data.vertices)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:58:08.428528+00:00", "type": "tool_call", "id": "chatcmpl-tool-b30242086301c8e0", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\n# ============================================================\n# SUZANNE — Blender's monkey head, as a bust\n# ============================================================\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\nsuzanne = bpy.context.active_object\nsuzanne.name = \"Suzanne\"\n\n# Add a simple bust base/pedestal under Suzanne\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\nbust_base = bpy.context.active_object\nbust_base.name = \"SuzanneBase\"\nbpy.ops.object.shade_smooth()\n\n# Taper the base slightly (classical bust pedestal)\nbpy.context.view_layer.objects.active = bust_base\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=3)\nbpy.ops.object.mode_set(mode='OBJECT')\n# Scale top vertices slightly\nmesh = bust_base.data\nfor v in mesh.vertices:\n    if v.co.z > 0.04:\n        v.co.x *= 0.7\n        v.co.y *= 0.7\n\n# Parent base to Suzanne for now\nbust_base.parent = suzanne\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\n\nprint(\"Suzanne and bust base built.\")\n\n# ============================================================\n# CHECKERED SPHERE — ray-tracing demo classic\n# ============================================================\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\nsphere = bpy.context.active_object\nsphere.name = \"CheckeredSphere\"\nbpy.ops.object.shade_smooth()\n\n# Add subsurf for perfectly smooth sphere\nmod = sphere.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\nprint(\"Checkered sphere built.\")\nresult = {\"suzanne_verts\": len(suzanne.data.vertices), \"sphere_verts\": len(sphere.data.vertices)}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}
{"ts": "2026-07-17T14:58:08.804348+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:58:45.105691+00:00", "type": "llm_call", "call_index": 10, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:58:08.804348+00:00", "finished_at": "2026-07-17T14:58:45.105691+00:00", "duration_s": 36.312999999994645, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:58:08.804348+00:00", "finished_at": "2026-07-17T14:58:45.105188+00:00", "duration_s": 36.312999999994645, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "55391", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:58:11 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300289-vZz8RIt51ix45mdaBHPi", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1a689d030b7a-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300289-vZz8RIt51ix45mdaBHPi\",\"object\":\"chat.completion\",\"created\":1784300289,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-b3944ff151600684\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":13761,\"completion_tokens\":1433,\"total_tokens\":15194,\"cost\":0.00705182196,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":13184,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00705182196,\"upstream_inference_prompt_cost\":0.00283364316,\"upstream_inference_completions_cost\":0.0042181788},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDAyODktdlp6OFJJdDUxaXg0NW1kYUJIUGkiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwMjg5LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBhZGQgdGhlIHN1cHBvcnRpbmcgY2xhc3NpY2FsIHByb3BzIOKAlCBJJ2xsIGNyZWF0ZSBhIHdpbmUgZ2xhc3MsIGEgYm9vaywgYW5kIHNvbWUgZnJ1aXQuIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBXSU5FIEdMQVNTIOKAlCBjbGFzc2ljYWwgc3RpbGwgbGlmZSBwcm9wXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiV2luZUdsYXNzTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB0aGUgd2luZSBnbGFzcyAocmFkaXVzLCBoZWlnaHQpIOKAlCBsYXRoZWRcXG5nbGFzc19wcm9maWxlID0gW1xcbiAgICAoMC4wMCwgMC4wMCksICAgICMgYmFzZSBjZW50ZXJcXG4gICAgKDAuMTQsIDAuMDApLCAgICAjIGJhc2UgZWRnZVxcbiAgICAoMC4xNSwgMC4wMSksICAgICMgYmFzZSBsaXBcXG4gICAgKDAuMTMsIDAuMDIpLCAgICAjIFxcbiAgICAoMC4wNCwgMC4wMyksICAgICMgc3RlbSBiYXNlXFxuICAgICgwLjAzNSwgMC4xMCksICAgIyBzdGVtXFxuICAgICgwLjAzNSwgMC4xOCksICAgIyBzdGVtXFxuICAgICgwLjA0LCAwLjI1KSwgICAgIyBib3dsIGJhc2VcXG4gICAgKDAuMDgsIDAuMzApLCAgICAjIGJvd2wgd2lkZW5pbmdcXG4gICAgKDAuMTIsIDAuMzYpLCAgICAjIFxcbiAgICAoMC4xNCwgMC40MiksICAgICMgYm93bCB3aWRlc3RcXG4gICAgKDAuMTM1LCAwLjQ4KSwgICAjIFxcbiAgICAoMC4xMSwgMC41MyksICAgICMgdGFwZXJpbmcgaW5cXG4gICAgKDAuMDgsIDAuNTcpLCAgICAjIFxcbiAgICAoMC4wNiwgMC42MCksICAgICMgcmltXFxuICAgICgwLjAwLCAwLjYwKSwgICAgIyBjZW50ZXIgdG9wIChvcGVuKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBnbGFzc19wcm9maWxlOlxcbiAgICByaW5nID0gW11cXG4gICAgaWYgciA8IDAuMDAxOlxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4oYWxsX3ZlcnRzKSAtIDEpOlxcbiAgICByaW5nX2EgPSBhbGxfdmVydHNbcmldXFxuICAgIHJpbmdfYiA9IGFsbF92ZXJ0c1tyaSArIDFdXFxuICAgIHJhLCBfID0gZ2xhc3NfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBnbGFzc19wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgRG9uJ3QgY2FwIHRoZSB0b3AgLSBsZWF2ZSBvcGVuXFxuICAgICAgICAgICAgcGFzc1xcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdsYXNzX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJXaW5lR2xhc3NcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGdsYXNzX29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gZ2xhc3Nfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCBzb2xpZGlmeSBmb3IgZ2xhc3MgdGhpY2tuZXNzXFxubW9kID0gZ2xhc3Nfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMDRcXG5tb2Qub2Zmc2V0ID0gMVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBPUEVOIEJPT0sg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQm9vayBiYXNlICh0d28gcGFnZXMgbWVldGluZyBhdCBzcGluZSlcXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX2N1YmVfYWRkKHNpemU9MSwgbG9jYXRpb249KDAsIDAsIDApKVxcbmJvb2sgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYm9vay5uYW1lID0gXFxcIk9wZW5Cb29rXFxcIlxcbmJvb2suc2NhbGUgPSAoMC40NSwgMC4zMiwgMC4wMylcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU2hhcGUgdGhlIHBhZ2VzIC0gY3JlYXRlIGEgVi1zaGFwZSBmb3Igb3BlbiBib29rXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJvb2tcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz04KVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J09CSkVDVCcpXFxuXFxubWVzaCA9IGJvb2suZGF0YVxcbiMgQ3JlYXRlIHRoZSBWLXNoYXBlOiBzcGluZSBpbiBjZW50ZXIgZGlwcyBkb3duLCBlZGdlcyBjdXJ2ZSB1cCBzbGlnaHRseVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICMgRGlzdGFuY2UgZnJvbSBjZW50ZXIgbGluZSAoeD0wIGlzIHNwaW5lKVxcbiAgICBkaXN0X2Zyb21fc3BpbmUgPSBhYnModi5jby54KVxcbiAgICAjIFBhZ2VzIGN1cnZlIHVwIGF0IGVkZ2VzXFxuICAgIHYuY28ueiArPSAwLjAyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDUpICoqIDEuNVxcbiAgICAjIFNwaW5lIGRpcHNcXG4gICAgaWYgZGlzdF9mcm9tX3NwaW5lIDwgMC4wNTpcXG4gICAgICAgIHYuY28ueiAtPSAwLjAxXFxuXFxuIyBBZGQgYSBzZWNvbmQgdGhpbiBjdWJlIGZvciB0aGUgY292ZXIgKGRhcmtlcilcXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX2N1YmVfYWRkKHNpemU9MSwgbG9jYXRpb249KDAsIDAsIC0wLjAyKSlcXG5jb3ZlciA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5jb3Zlci5uYW1lID0gXFxcIkJvb2tDb3ZlclxcXCJcXG5jb3Zlci5zY2FsZSA9ICgwLjQ4LCAwLjM0LCAwLjAxNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU2hhcGUgY292ZXIgdG8gbWF0Y2hcXG5tZXNoID0gY292ZXIuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgIHYuY28ueiArPSAwLjAyMiAqIChkaXN0X2Zyb21fc3BpbmUgLyAwLjQ4KSAqKiAxLjVcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgRlJVSVQg4oCUIGEgZmV3IG9yYW5nZXMvbGVtb25zIGZvciBjb2xvciBhbmQgbGlmZVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuZnJ1aXRzID0gW11cXG5mcnVpdF9jb2xvcnMgPSBbXFxuICAgICgoMC4xMCwgMCwgMCksIDAuMDksIFxcXCJPcmFuZ2UxXFxcIiksICAgIyBvcmFuZ2UsIHNsaWdodCBvZmZzZXRcXG4gICAgKCgwLjE4LCAwLjA4LCAwKSwgMC4wNzUsIFxcXCJPcmFuZ2UyXFxcIiksICAjIG9yYW5nZSwgZGlmZmVyZW50IHBvc2l0aW9uXFxuICAgICgoMC4wLCAwLjEyLCAwKSwgMC4wOCwgXFxcIkxlbW9uMVxcXCIpLCAgICMgbGVtb25cXG5dXFxuXFxuZm9yIGksIChwb3MsIHJhZGl1cywgbmFtZSkgaW4gZW51bWVyYXRlKGZydWl0X2NvbG9ycyk6XFxuICAgIGJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9cmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ19jb3VudD0xNiwgbG9jYXRpb249cG9zKVxcbiAgICBmcnVpdCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG4gICAgZnJ1aXQubmFtZSA9IG5hbWVcXG4gICAgIyBTcXVhc2ggc2xpZ2h0bHkgZm9yIGZydWl0IHNoYXBlXFxuICAgIGZydWl0LnNjYWxlID0gKDEuMCwgMS4wLCAwLjg4KVxcbiAgICBicHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBmcnVpdHMuYXBwZW5kKGZydWl0KVxcblxcbnByaW50KFxcXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcIm9iamVjdHNcXFwiOiBbXFxcIldpbmVHbGFzc1xcXCIsIFxcXCJPcGVuQm9va1xcXCIsIFxcXCJCb29rQ292ZXJcXFwiXSArIFtmLm5hbWUgZm9yIGYgaW4gZnJ1aXRzXX1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjoxMzc2MSwiY29tcGxldGlvbl90b2tlbnMiOjE0MzMsInRvdGFsX3Rva2VucyI6MTUxOTQsImNvc3QiOjAuMDA3MDUxODIxOTYsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MTMxODQsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA3MDUxODIxOTYsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDI4MzM2NDMxNiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDA0MjE4MTc4OH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# WINE GLASS — classical still life prop\n# ============================================================\nmesh = bpy.data.meshes.new(\"WineGlassMesh\")\nbm = bmesh.new()\n\n# Profile of the wine glass (radius, height) — lathed\nglass_profile = [\n    (0.00, 0.00),    # base center\n    (0.14, 0.00),    # base edge\n    (0.15, 0.01),    # base lip\n    (0.13, 0.02),    # \n    (0.04, 0.03),    # stem base\n    (0.035, 0.10),   # stem\n    (0.035, 0.18),   # stem\n    (0.04, 0.25),    # bowl base\n    (0.08, 0.30),    # bowl widening\n    (0.12, 0.36),    # \n    (0.14, 0.42),    # bowl widest\n    (0.135, 0.48),   # \n    (0.11, 0.53),    # tapering in\n    (0.08, 0.57),    # \n    (0.06, 0.60),    # rim\n    (0.00, 0.60),    # center top (open)\n]\n\nsegments = 48\nall_verts = []\nfor r, h in glass_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = glass_profile[ri]\n    rb, _ = glass_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            # Don't cap the top - leave open\n            pass\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nglass_obj = bpy.data.objects.new(\"WineGlass\", mesh)\nlink_obj(glass_obj)\nbpy.context.view_layer.objects.active = glass_obj\nbpy.ops.object.shade_smooth()\n\n# Add solidify for glass thickness\nmod = glass_obj.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.004\nmod.offset = 1\n\n# ============================================================\n# OPEN BOOK — classical still life prop\n# ============================================================\n# Book base (two pages meeting at spine)\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\nbook = bpy.context.active_object\nbook.name = \"OpenBook\"\nbook.scale = (0.45, 0.32, 0.03)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Shape the pages - create a V-shape for open book\nbpy.context.view_layer.objects.active = book\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=8)\nbpy.ops.object.mode_set(mode='OBJECT')\n\nmesh = book.data\n# Create the V-shape: spine in center dips down, edges curve up slightly\nfor v in mesh.vertices:\n    # Distance from center line (x=0 is spine)\n    dist_from_spine = abs(v.co.x)\n    # Pages curve up at edges\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\n    # Spine dips\n    if dist_from_spine < 0.05:\n        v.co.z -= 0.01\n\n# Add a second thin cube for the cover (darker)\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\ncover = bpy.context.active_object\ncover.name = \"BookCover\"\ncover.scale = (0.48, 0.34, 0.015)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Shape cover to match\nmesh = cover.data\nfor v in mesh.vertices:\n    dist_from_spine = abs(v.co.x)\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\n\n# ============================================================\n# FRUIT — a few oranges/lemons for color and life\n# ============================================================\nfruits = []\nfruit_colors = [\n    ((0.10, 0, 0), 0.09, \"Orange1\"),   # orange, slight offset\n    ((0.18, 0.08, 0), 0.075, \"Orange2\"),  # orange, different position\n    ((0.0, 0.12, 0), 0.08, \"Lemon1\"),   # lemon\n]\n\nfor i, (pos, radius, name) in enumerate(fruit_colors):\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\n    fruit = bpy.context.active_object\n    fruit.name = name\n    # Squash slightly for fruit shape\n    fruit.scale = (1.0, 1.0, 0.88)\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n    bpy.ops.object.shade_smooth()\n    fruits.append(fruit)\n\nprint(\"Wine glass, book, and fruit built.\")\nresult = {\"objects\": [\"WineGlass\", \"OpenBook\", \"BookCover\"] + [f.name for f in fruits]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}", "parse_error": null}], "tokens_in": 13761, "tokens_out": 1433, "cost_usd": 0.00705182196, "cached_tokens": 13184}, "error": null}
{"ts": "2026-07-17T14:58:45.107696+00:00", "type": "assistant", "text": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# WINE GLASS — classical still life prop\n# ============================================================\nmesh = bpy.data.meshes.new(\"WineGlassMesh\")\nbm = bmesh.new()\n\n# Profile of the wine glass (radius, height) — lathed\nglass_profile = [\n    (0.00, 0.00),    # base center\n    (0.14, 0.00),    # base edge\n    (0.15, 0.01),    # base lip\n    (0.13, 0.02),    # \n    (0.04, 0.03),    # stem base\n    (0.035, 0.10),   # stem\n    (0.035, 0.18),   # stem\n    (0.04, 0.25),    # bowl base\n    (0.08, 0.30),    # bowl widening\n    (0.12, 0.36),    # \n    (0.14, 0.42),    # bowl widest\n    (0.135, 0.48),   # \n    (0.11, 0.53),    # tapering in\n    (0.08, 0.57),    # \n    (0.06, 0.60),    # rim\n    (0.00, 0.60),    # center top (open)\n]\n\nsegments = 48\nall_verts = []\nfor r, h in glass_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = glass_profile[ri]\n    rb, _ = glass_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            # Don't cap the top - leave open\n            pass\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nglass_obj = bpy.data.objects.new(\"WineGlass\", mesh)\nlink_obj(glass_obj)\nbpy.context.view_layer.objects.active = glass_obj\nbpy.ops.object.shade_smooth()\n\n# Add solidify for glass thickness\nmod = glass_obj.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.004\nmod.offset = 1\n\n# ============================================================\n# OPEN BOOK — classical still life prop\n# ============================================================\n# Book base (two pages meeting at spine)\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\nbook = bpy.context.active_object\nbook.name = \"OpenBook\"\nbook.scale = (0.45, 0.32, 0.03)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Shape the pages - create a V-shape for open book\nbpy.context.view_layer.objects.active = book\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=8)\nbpy.ops.object.mode_set(mode='OBJECT')\n\nmesh = book.data\n# Create the V-shape: spine in center dips down, edges curve up slightly\nfor v in mesh.vertices:\n    # Distance from center line (x=0 is spine)\n    dist_from_spine = abs(v.co.x)\n    # Pages curve up at edges\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\n    # Spine dips\n    if dist_from_spine < 0.05:\n        v.co.z -= 0.01\n\n# Add a second thin cube for the cover (darker)\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\ncover = bpy.context.active_object\ncover.name = \"BookCover\"\ncover.scale = (0.48, 0.34, 0.015)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Shape cover to match\nmesh = cover.data\nfor v in mesh.vertices:\n    dist_from_spine = abs(v.co.x)\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\n\n# ============================================================\n# FRUIT — a few oranges/lemons for color and life\n# ============================================================\nfruits = []\nfruit_colors = [\n    ((0.10, 0, 0), 0.09, \"Orange1\"),   # orange, slight offset\n    ((0.18, 0.08, 0), 0.075, \"Orange2\"),  # orange, different position\n    ((0.0, 0.12, 0), 0.08, \"Lemon1\"),   # lemon\n]\n\nfor i, (pos, radius, name) in enumerate(fruit_colors):\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\n    fruit = bpy.context.active_object\n    fruit.name = name\n    # Squash slightly for fruit shape\n    fruit.scale = (1.0, 1.0, 0.88)\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n    bpy.ops.object.shade_smooth()\n    fruits.append(fruit)\n\nprint(\"Wine glass, book, and fruit built.\")\nresult = {\"objects\": [\"WineGlass\", \"OpenBook\", \"BookCover\"] + [f.name for f in fruits]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:58:45.107696+00:00", "type": "tool_call", "id": "chatcmpl-tool-b3944ff151600684", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector, Matrix\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# WINE GLASS — classical still life prop\n# ============================================================\nmesh = bpy.data.meshes.new(\"WineGlassMesh\")\nbm = bmesh.new()\n\n# Profile of the wine glass (radius, height) — lathed\nglass_profile = [\n    (0.00, 0.00),    # base center\n    (0.14, 0.00),    # base edge\n    (0.15, 0.01),    # base lip\n    (0.13, 0.02),    # \n    (0.04, 0.03),    # stem base\n    (0.035, 0.10),   # stem\n    (0.035, 0.18),   # stem\n    (0.04, 0.25),    # bowl base\n    (0.08, 0.30),    # bowl widening\n    (0.12, 0.36),    # \n    (0.14, 0.42),    # bowl widest\n    (0.135, 0.48),   # \n    (0.11, 0.53),    # tapering in\n    (0.08, 0.57),    # \n    (0.06, 0.60),    # rim\n    (0.00, 0.60),    # center top (open)\n]\n\nsegments = 48\nall_verts = []\nfor r, h in glass_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = glass_profile[ri]\n    rb, _ = glass_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            # Don't cap the top - leave open\n            pass\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nglass_obj = bpy.data.objects.new(\"WineGlass\", mesh)\nlink_obj(glass_obj)\nbpy.context.view_layer.objects.active = glass_obj\nbpy.ops.object.shade_smooth()\n\n# Add solidify for glass thickness\nmod = glass_obj.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.004\nmod.offset = 1\n\n# ============================================================\n# OPEN BOOK — classical still life prop\n# ============================================================\n# Book base (two pages meeting at spine)\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\nbook = bpy.context.active_object\nbook.name = \"OpenBook\"\nbook.scale = (0.45, 0.32, 0.03)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Shape the pages - create a V-shape for open book\nbpy.context.view_layer.objects.active = book\nbpy.ops.object.mode_set(mode='EDIT')\nbpy.ops.mesh.select_all(action='SELECT')\nbpy.ops.mesh.subdivide(number_cuts=8)\nbpy.ops.object.mode_set(mode='OBJECT')\n\nmesh = book.data\n# Create the V-shape: spine in center dips down, edges curve up slightly\nfor v in mesh.vertices:\n    # Distance from center line (x=0 is spine)\n    dist_from_spine = abs(v.co.x)\n    # Pages curve up at edges\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\n    # Spine dips\n    if dist_from_spine < 0.05:\n        v.co.z -= 0.01\n\n# Add a second thin cube for the cover (darker)\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\ncover = bpy.context.active_object\ncover.name = \"BookCover\"\ncover.scale = (0.48, 0.34, 0.015)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Shape cover to match\nmesh = cover.data\nfor v in mesh.vertices:\n    dist_from_spine = abs(v.co.x)\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\n\n# ============================================================\n# FRUIT — a few oranges/lemons for color and life\n# ============================================================\nfruits = []\nfruit_colors = [\n    ((0.10, 0, 0), 0.09, \"Orange1\"),   # orange, slight offset\n    ((0.18, 0.08, 0), 0.075, \"Orange2\"),  # orange, different position\n    ((0.0, 0.12, 0), 0.08, \"Lemon1\"),   # lemon\n]\n\nfor i, (pos, radius, name) in enumerate(fruit_colors):\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\n    fruit = bpy.context.active_object\n    fruit.name = name\n    # Squash slightly for fruit shape\n    fruit.scale = (1.0, 1.0, 0.88)\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n    bpy.ops.object.shade_smooth()\n    fruits.append(fruit)\n\nprint(\"Wine glass, book, and fruit built.\")\nresult = {\"objects\": [\"WineGlass\", \"OpenBook\", \"BookCover\"] + [f.name for f in fruits]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}
{"ts": "2026-07-17T14:58:46.391819+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:59:05.041430+00:00", "type": "llm_call", "call_index": 11, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:58:46.392819+00:00", "finished_at": "2026-07-17T14:59:05.041430+00:00", "duration_s": 18.65600000001723, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:58:46.392819+00:00", "finished_at": "2026-07-17T14:59:05.039923+00:00", "duration_s": 18.64000000001397, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "61002", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:58:48 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300327-pIYBuVZia6QXxFsOu8P6", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1b537cafceb3-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300327-pIYBuVZia6QXxFsOu8P6\",\"object\":\"chat.completion\",\"created\":1784300327,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":15270,\"completion_tokens\":736,\"total_tokens\":16006,\"cost\":0.00597417,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":13760,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00597417,\"upstream_inference_prompt_cost\":0.0038076804,\"upstream_inference_completions_cost\":0.0021664896},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDAzMjctcElZQnVWWmlhNlFYeEZzT3U4UDYiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwMzI3LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjE1MjcwLCJjb21wbGV0aW9uX3Rva2VucyI6NzM2LCJ0b3RhbF90b2tlbnMiOjE2MDA2LCJjb3N0IjowLjAwNTk3NDE3LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjEzNzYwLCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwNTk3NDE3LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDAzODA3NjgwNCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAyMTY2NDg5Nn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# COMPOSITION: Position all objects on the table\n# Camera will be at slightly-elevated angle, ~50mm equivalent\n# Teapot commands the arrangement (center-hero), others grouped around\n# ============================================================\n\n# Table surface is at z=0\n# Camera will look from front-left, slightly elevated\n\n# --- Utah Teapot (hero, center, commanding) ---\nteapot = bpy.data.objects[\"UtahTeapot\"]\nteapot.location = (-0.1, 0.1, 0.0)\nteapot.rotation_euler = (0, 0, math.radians(-25))\nteapot.scale = (0.85, 0.85, 0.85)\n\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\nbunny = bpy.data.objects[\"StanfordBunny\"]\nbunny.location = (-1.15, 0.25, 0.03)\nbunny.rotation_euler = (0, 0, math.radians(40))\nbunny.scale = (1.3, 1.3, 1.3)\n\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\nsuzanne = bpy.data.objects[\"Suzanne\"]\nsuzanne.location = (1.0, -0.05, 0.18)\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\n\n# --- Checkered Sphere (front-center, in front of teapot) ---\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nsphere.location = (0.15, -0.55, 0.22)\n\n# --- Wine Glass (right side, back) ---\nglass = bpy.data.objects[\"WineGlass\"]\nglass.location = (1.55, 0.3, 0.0)\nglass.scale = (1.1, 1.1, 1.1)\n\n# --- Open Book (left-front, partially under bunny) ---\nbook = bpy.data.objects[\"OpenBook\"]\nbook.location = (-0.6, -0.7, 0.02)\nbook.rotation_euler = (0, 0, math.radians(15))\n\ncover = bpy.data.objects[\"BookCover\"]\ncover.location = book.location\ncover.rotation_euler = book.rotation_euler\n\n# --- Fruit (clustered near front-right) ---\nbpy.data.objects[\"Orange1\"].location = (0.85, -0.75, 0.09)\nbpy.data.objects[\"Orange1\"].rotation_euler = (0, 0, math.radians(30))\n\nbpy.data.objects[\"Orange2\"].location = (1.05, -0.65, 0.075)\nbpy.data.objects[\"Orange2\"].rotation_euler = (math.radians(20), 0, 0)\n\nbpy.data.objects[\"Lemon1\"].location = (0.7, -0.55, 0.08)\nbpy.data.objects[\"Lemon1\"].rotation_euler = (math.radians(15), 0, math.radians(45))\n\nprint(\"All objects positioned.\")\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}", "parse_error": null}], "tokens_in": 15270, "tokens_out": 736, "cost_usd": 0.00597417, "cached_tokens": 13760}, "error": null}
{"ts": "2026-07-17T14:59:05.043440+00:00", "type": "assistant", "text": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# COMPOSITION: Position all objects on the table\n# Camera will be at slightly-elevated angle, ~50mm equivalent\n# Teapot commands the arrangement (center-hero), others grouped around\n# ============================================================\n\n# Table surface is at z=0\n# Camera will look from front-left, slightly elevated\n\n# --- Utah Teapot (hero, center, commanding) ---\nteapot = bpy.data.objects[\"UtahTeapot\"]\nteapot.location = (-0.1, 0.1, 0.0)\nteapot.rotation_euler = (0, 0, math.radians(-25))\nteapot.scale = (0.85, 0.85, 0.85)\n\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\nbunny = bpy.data.objects[\"StanfordBunny\"]\nbunny.location = (-1.15, 0.25, 0.03)\nbunny.rotation_euler = (0, 0, math.radians(40))\nbunny.scale = (1.3, 1.3, 1.3)\n\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\nsuzanne = bpy.data.objects[\"Suzanne\"]\nsuzanne.location = (1.0, -0.05, 0.18)\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\n\n# --- Checkered Sphere (front-center, in front of teapot) ---\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nsphere.location = (0.15, -0.55, 0.22)\n\n# --- Wine Glass (right side, back) ---\nglass = bpy.data.objects[\"WineGlass\"]\nglass.location = (1.55, 0.3, 0.0)\nglass.scale = (1.1, 1.1, 1.1)\n\n# --- Open Book (left-front, partially under bunny) ---\nbook = bpy.data.objects[\"OpenBook\"]\nbook.location = (-0.6, -0.7, 0.02)\nbook.rotation_euler = (0, 0, math.radians(15))\n\ncover = bpy.data.objects[\"BookCover\"]\ncover.location = book.location\ncover.rotation_euler = book.rotation_euler\n\n# --- Fruit (clustered near front-right) ---\nbpy.data.objects[\"Orange1\"].location = (0.85, -0.75, 0.09)\nbpy.data.objects[\"Orange1\"].rotation_euler = (0, 0, math.radians(30))\n\nbpy.data.objects[\"Orange2\"].location = (1.05, -0.65, 0.075)\nbpy.data.objects[\"Orange2\"].rotation_euler = (math.radians(20), 0, 0)\n\nbpy.data.objects[\"Lemon1\"].location = (0.7, -0.55, 0.08)\nbpy.data.objects[\"Lemon1\"].rotation_euler = (math.radians(15), 0, math.radians(45))\n\nprint(\"All objects positioned.\")\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:59:05.043440+00:00", "type": "tool_call", "id": "chatcmpl-tool-a11b11ab0c461694", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# COMPOSITION: Position all objects on the table\n# Camera will be at slightly-elevated angle, ~50mm equivalent\n# Teapot commands the arrangement (center-hero), others grouped around\n# ============================================================\n\n# Table surface is at z=0\n# Camera will look from front-left, slightly elevated\n\n# --- Utah Teapot (hero, center, commanding) ---\nteapot = bpy.data.objects[\"UtahTeapot\"]\nteapot.location = (-0.1, 0.1, 0.0)\nteapot.rotation_euler = (0, 0, math.radians(-25))\nteapot.scale = (0.85, 0.85, 0.85)\n\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\nbunny = bpy.data.objects[\"StanfordBunny\"]\nbunny.location = (-1.15, 0.25, 0.03)\nbunny.rotation_euler = (0, 0, math.radians(40))\nbunny.scale = (1.3, 1.3, 1.3)\n\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\nsuzanne = bpy.data.objects[\"Suzanne\"]\nsuzanne.location = (1.0, -0.05, 0.18)\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\n\n# --- Checkered Sphere (front-center, in front of teapot) ---\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nsphere.location = (0.15, -0.55, 0.22)\n\n# --- Wine Glass (right side, back) ---\nglass = bpy.data.objects[\"WineGlass\"]\nglass.location = (1.55, 0.3, 0.0)\nglass.scale = (1.1, 1.1, 1.1)\n\n# --- Open Book (left-front, partially under bunny) ---\nbook = bpy.data.objects[\"OpenBook\"]\nbook.location = (-0.6, -0.7, 0.02)\nbook.rotation_euler = (0, 0, math.radians(15))\n\ncover = bpy.data.objects[\"BookCover\"]\ncover.location = book.location\ncover.rotation_euler = book.rotation_euler\n\n# --- Fruit (clustered near front-right) ---\nbpy.data.objects[\"Orange1\"].location = (0.85, -0.75, 0.09)\nbpy.data.objects[\"Orange1\"].rotation_euler = (0, 0, math.radians(30))\n\nbpy.data.objects[\"Orange2\"].location = (1.05, -0.65, 0.075)\nbpy.data.objects[\"Orange2\"].rotation_euler = (math.radians(20), 0, 0)\n\nbpy.data.objects[\"Lemon1\"].location = (0.7, -0.55, 0.08)\nbpy.data.objects[\"Lemon1\"].rotation_euler = (math.radians(15), 0, math.radians(45))\n\nprint(\"All objects positioned.\")\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}
{"ts": "2026-07-17T14:59:05.787153+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T14:59:35.219634+00:00", "type": "llm_call", "call_index": 12, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:59:05.788153+00:00", "finished_at": "2026-07-17T14:59:35.218633+00:00", "duration_s": 29.437999999994645, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:59:05.788153+00:00", "finished_at": "2026-07-17T14:59:35.218633+00:00", "duration_s": 29.437999999994645, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "66144", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:59:08 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300346-mwi7WJl0AvJpMdNbMy6B", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1bcca9972d40-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300346-mwi7WJl0AvJpMdNbMy6B\",\"object\":\"chat.completion\",\"created\":1784300346,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":16987,\"completion_tokens\":1174,\"total_tokens\":18161,\"cost\":0.00774897348,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":15232,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00774897348,\"upstream_inference_prompt_cost\":0.00429318708,\"upstream_inference_completions_cost\":0.0034557864},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAwMzQ2LW13aTdXSmwwQXZKcE1kTmJNeTZCIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMDM0NiwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgY3JlYXRlIGFsbCB0aGUgbWF0ZXJpYWxzLiBUaGlzIGlzIHdoZXJlIHRoZSBzdG9yeXRlbGxpbmcgaGFwcGVucyDigJQgYWdlZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldCBjbG90aCwgcG9saXNoZWQgY2hyb21lLiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC05NzFhZTA5YjA5Y2Q3YzdkIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBNQVRFUklBTFNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIFRFQVBPVDogR2xhemVkIGNlcmFtaWMgd2l0aCBzaWx2ZXIgYWNjZW50cyAoVmVybWVlci13b3J0aHkpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC43MiwgMC42OCwgMC42MCwgMS4wKSAgIyB3YXJtIGNyZWFtXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG4jIEFkZCBzdWJ0bGUgbm9pc2UgZm9yIGNlcmFtaWMgaW1wZXJmZWN0aW9uXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDM1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xNVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxuIyBDb2xvciB2YXJpYXRpb25cXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoLTIwMCwgMTAwKSlcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlMi5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSAyLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjYsIDAuNTgsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC43NiwgMC43MiwgMC42NCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBpZiBvYmouZGF0YS5tYXRlcmlhbHM6XFxuICAgICAgICBvYmouZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG4gICAgZWxzZTpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDIuIFNUQU5GT1JEIEJVTk5ZOiBCcm9uemUvcGF0aW5hdGVkIHNjdWxwdHVyZSBtYXRlcmlhbCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0J1bm55QnJvbnplXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjU1LCAwLjQwLCAwLjI1LCAxLjApICAjIGJyb256ZVxcbmJzZGYuaW5wdXRzWydNZXRhbGxpYyddLmRlZmF1bHRfdmFsdWUgPSAxLjBcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMzVcXG5cXG4jIFBhdGluYSB2YXJpYXRpb24gKGdyZWVuaXNoIHBhdGNoZXMpXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMjUsIDAuMzgsIDAuMjgsIDEuMCkgICMgcGF0aW5hIGdyZWVuXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG4jIFJvdWdobmVzcyB2YXJpYXRpb25cXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXSlcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNTAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJ1bm55ID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiU3RhbmZvcmRCdW5ueVxcXCJdXFxuaWYgYnVubnkuZGF0YS5tYXRlcmlhbHM6XFxuICAgIGJ1bm55LmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X21hdFxcXCI6IFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiLCBcXFwiYnVubnlfbWF0XFxcIjogXFxcIk1fQnVubnlCcm9uemVcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjE2OTg3LCJjb21wbGV0aW9uX3Rva2VucyI6MTE3NCwidG90YWxfdG9rZW5zIjoxODE2MSwiY29zdCI6MC4wMDc3NDg5NzM0OCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjoxNTIzMiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDc3NDg5NzM0OCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNDI5MzE4NzA4LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDM0NTU3ODY0fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# MATERIALS\n# ============================================================\n\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\nmat, nt = create_material(\"M_TeapotCeramic\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\nbsdf.inputs['Roughness'].default_value = 0.25\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n# Add subtle noise for ceramic imperfection\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\nnoise.inputs['Scale'].default_value = 35.0\nnoise.inputs['Detail'].default_value = 8.0\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\nbump.inputs['Strength'].default_value = 0.15\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n# Color variation\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\nnoise2.inputs['Scale'].default_value = 8.0\nnoise2.inputs['Detail'].default_value = 2.0\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nfor name in [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]:\n    obj = bpy.data.objects[name]\n    if obj.data.materials:\n        obj.data.materials[0] = mat\n    else:\n        obj.data.materials.append(mat)\n\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\nmat, nt = create_material(\"M_BunnyBronze\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.35\n\n# Patina variation (greenish patches)\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\nnoise.inputs['Scale'].default_value = 4.0\nnoise.inputs['Detail'].default_value = 6.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Roughness variation\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\nbump.inputs['Strength'].default_value = 0.3\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\nnoise3.inputs['Scale'].default_value = 50.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbunny = bpy.data.objects[\"StanfordBunny\"]\nif bunny.data.materials:\n    bunny.data.materials[0] = mat\nelse:\n    bunny.data.materials.append(mat)\n\nprint(\"Teapot and bunny materials created.\")\nresult = {\"teapot_mat\": \"M_TeapotCeramic\", \"bunny_mat\": \"M_BunnyBronze\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}", "parse_error": null}], "tokens_in": 16987, "tokens_out": 1174, "cost_usd": 0.00774897348, "cached_tokens": 15232}, "error": null}
{"ts": "2026-07-17T14:59:35.221138+00:00", "type": "assistant", "text": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# MATERIALS\n# ============================================================\n\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\nmat, nt = create_material(\"M_TeapotCeramic\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\nbsdf.inputs['Roughness'].default_value = 0.25\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n# Add subtle noise for ceramic imperfection\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\nnoise.inputs['Scale'].default_value = 35.0\nnoise.inputs['Detail'].default_value = 8.0\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\nbump.inputs['Strength'].default_value = 0.15\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n# Color variation\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\nnoise2.inputs['Scale'].default_value = 8.0\nnoise2.inputs['Detail'].default_value = 2.0\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nfor name in [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]:\n    obj = bpy.data.objects[name]\n    if obj.data.materials:\n        obj.data.materials[0] = mat\n    else:\n        obj.data.materials.append(mat)\n\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\nmat, nt = create_material(\"M_BunnyBronze\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.35\n\n# Patina variation (greenish patches)\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\nnoise.inputs['Scale'].default_value = 4.0\nnoise.inputs['Detail'].default_value = 6.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Roughness variation\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\nbump.inputs['Strength'].default_value = 0.3\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\nnoise3.inputs['Scale'].default_value = 50.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbunny = bpy.data.objects[\"StanfordBunny\"]\nif bunny.data.materials:\n    bunny.data.materials[0] = mat\nelse:\n    bunny.data.materials.append(mat)\n\nprint(\"Teapot and bunny materials created.\")\nresult = {\"teapot_mat\": \"M_TeapotCeramic\", \"bunny_mat\": \"M_BunnyBronze\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T14:59:35.221138+00:00", "type": "tool_call", "id": "chatcmpl-tool-971ae09b09cd7c7d", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# MATERIALS\n# ============================================================\n\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\nmat, nt = create_material(\"M_TeapotCeramic\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\nbsdf.inputs['Roughness'].default_value = 0.25\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n# Add subtle noise for ceramic imperfection\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\nnoise.inputs['Scale'].default_value = 35.0\nnoise.inputs['Detail'].default_value = 8.0\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\nbump.inputs['Strength'].default_value = 0.15\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n# Color variation\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\nnoise2.inputs['Scale'].default_value = 8.0\nnoise2.inputs['Detail'].default_value = 2.0\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nfor name in [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]:\n    obj = bpy.data.objects[name]\n    if obj.data.materials:\n        obj.data.materials[0] = mat\n    else:\n        obj.data.materials.append(mat)\n\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\nmat, nt = create_material(\"M_BunnyBronze\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.35\n\n# Patina variation (greenish patches)\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\nnoise.inputs['Scale'].default_value = 4.0\nnoise.inputs['Detail'].default_value = 6.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Roughness variation\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\nbump.inputs['Strength'].default_value = 0.3\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\nnoise3.inputs['Scale'].default_value = 50.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbunny = bpy.data.objects[\"StanfordBunny\"]\nif bunny.data.materials:\n    bunny.data.materials[0] = mat\nelse:\n    bunny.data.materials.append(mat)\n\nprint(\"Teapot and bunny materials created.\")\nresult = {\"teapot_mat\": \"M_TeapotCeramic\", \"bunny_mat\": \"M_BunnyBronze\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}
{"ts": "2026-07-17T14:59:36.215058+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:00:06.805062+00:00", "type": "llm_call", "call_index": 13, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T14:59:36.215058+00:00", "finished_at": "2026-07-17T15:00:06.805062+00:00", "duration_s": 30.578000000008615, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T14:59:36.215058+00:00", "finished_at": "2026-07-17T15:00:06.805062+00:00", "duration_s": 30.578000000008615, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "70676", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 14:59:38 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300376-DF6THMELSRoL9f2Q2r1w", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1c8aee383eaf-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300376-DF6THMELSRoL9f2Q2r1w\",\"object\":\"chat.completion\",\"created\":1784300376,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":18222,\"completion_tokens\":1208,\"total_tokens\":19430,\"cost\":0.0076878804,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":16960,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0076878804,\"upstream_inference_prompt_cost\":0.0041320116,\"upstream_inference_completions_cost\":0.0035558688},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAwMzc2LURGNlRITUVMU1JvTDlmMlEycjF3Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMDM3NiwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWE1MDgyY2U4YzAwOWJlYTciLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gMy4gU1VaQU5ORTogTWFyYmxlIGJ1c3QgbWF0ZXJpYWwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg1LCAwLjgzLCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcblxcbiMgTWFyYmxlIHZlaW5pbmdcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAzLjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSAyLjBcXG5ub2lzZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gMS41XFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoLTYwMCwgMTAwKSlcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKC0yMDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbMl0pICAjIEFcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snQ29sb3InXSwgbWl4LmlucHV0c1szXSkgICMgQlxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhtaXgub3V0cHV0c1syXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjgyLCAwLjgwLCAwLjc1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNSwgMC40MiwgMC4zOCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjFcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBoaXN0b3J5TWF0XFxuZWxzZTpcXG4gICAgc3V6YW5uZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgQnVzdCBiYXNlIC0gZGFya2VyIG1hcmJsZVxcbm1hdF9iYXNlLCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9CdXN0QmFzZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zLCAwLjI3LCAwLjIzLCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5iYXNlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiU3V6YW5uZUJhc2VcXFwiXVxcbmlmIGJhc2UuZGF0YS5tYXRlcmlhbHM6XFxuICAgIGJhc2UuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfYmFzZVxcbmVsc2U6XFxuICAgIGJhc2UuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9iYXNlKVxcblxcbiMgLS0tIDQuIENIRUNLRVJFRCBTUEhFUkU6IFBvbGlzaGVkIGNocm9tZSB3aXRoIGNoZWNrZXIgcGF0dGVybiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NoZWNrZXJlZFNwaGVyZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoODAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoNDAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44LCAwLjgsIDAuOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydNZXRhbGxpYyddLmRlZmF1bHRfdmFsdWUgPSAxLjBcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDIgICMgdmVyeSBwb2xpc2hlZFxcblxcbiMgQ2hlY2tlciBwYXR0ZXJuXFxuY2hlY2tlciA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleENoZWNrZXInLCAoMCwgMCkpXFxuY2hlY2tlci5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMjAwLCAwKSlcXG5udC5saW5rcy5uZXcoY2hlY2tlci5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA1LCAwLjA1LCAwLjA1LCAxLjApICAjIGRhcmsgc3F1YXJlc1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjk1LCAwLjk1LCAwLjk1LCAxLjApICAjIGxpZ2h0IHNxdWFyZXNcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuaWYgc3BoZXJlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzcGhlcmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBzcGhlcmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiU3V6YW5uZSwgYnVzdCBiYXNlLCBhbmQgY2hlY2tlcmVkIHNwaGVyZSBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjoxODIyMiwiY29tcGxldGlvbl90b2tlbnMiOjEyMDgsInRvdGFsX3Rva2VucyI6MTk0MzAsImNvc3QiOjAuMDA3Njg3ODgwNCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjoxNjk2MCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDc2ODc4ODA0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA0MTMyMDExNiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAzNTU1ODY4OH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 3. SUZANNE: Marble bust material ---\nmat, nt = create_material(\"M_SuzanneMarble\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\nbsdf.inputs['Roughness'].default_value = 0.3\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n\n# Marble veining\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\nnoise.inputs['Scale'].default_value = 3.0\nnoise.inputs['Detail'].default_value = 2.0\nnoise.inputs['Distortion'].default_value = 1.5\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\nwave.inputs['Scale'].default_value = 2.0\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\nmix.data_type = 'RGBA'\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Subtle bump\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\nbump.inputs['Strength'].default_value = 0.1\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\nnoise3.inputs['Scale'].default_value = 80.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nsuzanne = bpy.data.objects[\"Suzanne\"]\nif suzanne.data.materials:\n    suzanne.data.materials[0] = historyMat\nelse:\n    suzanne.data.materials.append(mat)\n\n# Bust base - darker marble\nmat_base, nt = create_material(\"M_BustBase\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.4\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbase = bpy.data.objects[\"SuzanneBase\"]\nif base.data.materials:\n    base.data.materials[0] = mat_base\nelse:\n    base.data.materials.append(mat_base)\n\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\nmat, nt = create_material(\"M_CheckeredSphere\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\n\n# Checker pattern\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\nchecker.inputs['Scale'].default_value = 12.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nif sphere.data.materials:\n    sphere.data.materials[0] = mat\nelse:\n    sphere.data.materials.append(mat)\n\nprint(\"Suzanne, bust base, and checkered sphere materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 18222, "tokens_out": 1208, "cost_usd": 0.0076878804, "cached_tokens": 16960}, "error": null}
{"ts": "2026-07-17T15:00:06.807572+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 3. SUZANNE: Marble bust material ---\nmat, nt = create_material(\"M_SuzanneMarble\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\nbsdf.inputs['Roughness'].default_value = 0.3\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n\n# Marble veining\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\nnoise.inputs['Scale'].default_value = 3.0\nnoise.inputs['Detail'].default_value = 2.0\nnoise.inputs['Distortion'].default_value = 1.5\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\nwave.inputs['Scale'].default_value = 2.0\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\nmix.data_type = 'RGBA'\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Subtle bump\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\nbump.inputs['Strength'].default_value = 0.1\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\nnoise3.inputs['Scale'].default_value = 80.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nsuzanne = bpy.data.objects[\"Suzanne\"]\nif suzanne.data.materials:\n    suzanne.data.materials[0] = historyMat\nelse:\n    suzanne.data.materials.append(mat)\n\n# Bust base - darker marble\nmat_base, nt = create_material(\"M_BustBase\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.4\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbase = bpy.data.objects[\"SuzanneBase\"]\nif base.data.materials:\n    base.data.materials[0] = mat_base\nelse:\n    base.data.materials.append(mat_base)\n\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\nmat, nt = create_material(\"M_CheckeredSphere\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\n\n# Checker pattern\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\nchecker.inputs['Scale'].default_value = 12.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nif sphere.data.materials:\n    sphere.data.materials[0] = mat\nelse:\n    sphere.data.materials.append(mat)\n\nprint(\"Suzanne, bust base, and checkered sphere materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:00:06.807572+00:00", "type": "tool_call", "id": "chatcmpl-tool-a5082ce8c009bea7", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 3. SUZANNE: Marble bust material ---\nmat, nt = create_material(\"M_SuzanneMarble\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\nbsdf.inputs['Roughness'].default_value = 0.3\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n\n# Marble veining\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\nnoise.inputs['Scale'].default_value = 3.0\nnoise.inputs['Detail'].default_value = 2.0\nnoise.inputs['Distortion'].default_value = 1.5\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\nwave.inputs['Scale'].default_value = 2.0\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\nmix.data_type = 'RGBA'\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Subtle bump\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\nbump.inputs['Strength'].default_value = 0.1\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\nnoise3.inputs['Scale'].default_value = 80.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nsuzanne = bpy.data.objects[\"Suzanne\"]\nif suzanne.data.materials:\n    suzanne.data.materials[0] = historyMat\nelse:\n    suzanne.data.materials.append(mat)\n\n# Bust base - darker marble\nmat_base, nt = create_material(\"M_BustBase\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.4\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbase = bpy.data.objects[\"SuzanneBase\"]\nif base.data.materials:\n    base.data.materials[0] = mat_base\nelse:\n    base.data.materials.append(mat_base)\n\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\nmat, nt = create_material(\"M_CheckeredSphere\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\n\n# Checker pattern\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\nchecker.inputs['Scale'].default_value = 12.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nif sphere.data.materials:\n    sphere.data.materials[0] = mat\nelse:\n    sphere.data.materials.append(mat)\n\nprint(\"Suzanne, bust base, and checkered sphere materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:00:07.604785+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:00:13.803245+00:00", "type": "llm_call", "call_index": 14, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:00:07.604785+00:00", "finished_at": "2026-07-17T15:00:13.802738+00:00", "duration_s": 6.187000000005355, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:00:07.604785+00:00", "finished_at": "2026-07-17T15:00:13.801739+00:00", "duration_s": 6.187000000005355, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "75102", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:00:10 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300408-otdQ7KhnRhLx6YYIWnk8", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1d4f1e70a6b0-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300408-otdQ7KhnRhLx6YYIWnk8\",\"object\":\"chat.completion\",\"created\":1784300408,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"refusal\":null,\"reasoning\":\"I noticed a bug - I used `historyMat` instead of `mat` for Suzanne. Let me fix that.\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"I noticed a bug - I used `historyMat` instead of `mat` for Suzanne. Let me fix that.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":19478,\"completion_tokens\":176,\"total_tokens\":19654,\"cost\":0.00489906024,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":18176,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00489906024,\"upstream_inference_prompt_cost\":0.00438098664,\"upstream_inference_completions_cost\":0.0005180736},\"completion_tokens_details\":{\"reasoning_tokens\":21,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMDQwOC1vdGRRN0toblJoTHg2WVlJV25rOCIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDA0MDgsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSBhIGJ1ZyDigJQgSSByZWZlcmVuY2VkIGBoaXN0b3J5TWF0YCBpbnN0ZWFkIG9mIGBtYXRgIGZvciBTdXphbm5lLiBMZXQgbWUgZml4IHRoYXQgYW5kIGNvbnRpbnVlIHdpdGggdGhlIGNsb3RoIGFuZCBlbnZpcm9ubWVudCBtYXRlcmlhbHMuIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjoiSSBub3RpY2VkIGEgYnVnIC0gSSB1c2VkIGBoaXN0b3J5TWF0YCBpbnN0ZWFkIG9mIGBtYXRgIGZvciBTdXphbm5lLiBMZXQgbWUgZml4IHRoYXQuIiwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XSwicmVhc29uaW5nX2RldGFpbHMiOlt7InR5cGUiOiJyZWFzb25pbmcudGV4dCIsInRleHQiOiJJIG5vdGljZWQgYSBidWcgLSBJIHVzZWQgYGhpc3RvcnlNYXRgIGluc3RlYWQgb2YgYG1hdGAgZm9yIFN1emFubmUuIExldCBtZSBmaXggdGhhdC4iLCJmb3JtYXQiOiJ1bmtub3duIiwiaW5kZXgiOjB9XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MTk0NzgsImNvbXBsZXRpb25fdG9rZW5zIjoxNzYsInRvdGFsX3Rva2VucyI6MTk2NTQsImNvc3QiOjAuMDA0ODk5MDYwMjQsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MTgxNzYsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA0ODk5MDYwMjQsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDQzODA5ODY2NCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAwNTE4MDczNn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MjEsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Fix Suzanne material assignment\nmat_suzanne = bpy.data.materials.get(\"M_SuzanneMarble\")\nsuzanne = bpy.data.objects[\"Suzanne\"]\nif suzanne.data.materials:\n    suzanne.data.materials[0] = mat_suzanne\nelse:\n    suzanne.data.materials.append(mat_suzanne)\n\nprint(\"Fixed Suzanne material.\")\nresult = {\"suzanne_materials\": [m.name for m in suzanne.data.materials]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}", "parse_error": null}], "tokens_in": 19478, "tokens_out": 176, "cost_usd": 0.00489906024, "cached_tokens": 18176}, "error": null}
{"ts": "2026-07-17T15:00:13.804250+00:00", "type": "assistant", "text": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Fix Suzanne material assignment\nmat_suzanne = bpy.data.materials.get(\"M_SuzanneMarble\")\nsuzanne = bpy.data.objects[\"Suzanne\"]\nif suzanne.data.materials:\n    suzanne.data.materials[0] = mat_suzanne\nelse:\n    suzanne.data.materials.append(mat_suzanne)\n\nprint(\"Fixed Suzanne material.\")\nresult = {\"suzanne_materials\": [m.name for m in suzanne.data.materials]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:00:13.804250+00:00", "type": "tool_call", "id": "chatcmpl-tool-b99d874b987317e9", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Fix Suzanne material assignment\nmat_suzanne = bpy.data.materials.get(\"M_SuzanneMarble\")\nsuzanne = bpy.data.objects[\"Suzanne\"]\nif suzanne.data.materials:\n    suzanne.data.materials[0] = mat_suzanne\nelse:\n    suzanne.data.materials.append(mat_suzanne)\n\nprint(\"Fixed Suzanne material.\")\nresult = {\"suzanne_materials\": [m.name for m in suzanne.data.materials]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}
{"ts": "2026-07-17T15:00:13.965561+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:00:50.346031+00:00", "type": "llm_call", "call_index": 15, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:00:13.965561+00:00", "finished_at": "2026-07-17T15:00:50.346031+00:00", "duration_s": 36.375, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:00:13.965561+00:00", "finished_at": "2026-07-17T15:00:50.346031+00:00", "duration_s": 36.375, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "76084", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:00:18 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300414-fG1hcKmvNnOqYi7Y3Fcn", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1d76c8b5ecb0-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300414-fG1hcKmvNnOqYi7Y3Fcn\",\"object\":\"chat.completion\",\"created\":1784300414,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":19681,\"completion_tokens\":1410,\"total_tokens\":21091,\"cost\":0.00774538764,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":19456,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00774538764,\"upstream_inference_prompt_cost\":0.00359491164,\"upstream_inference_completions_cost\":0.004150476},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA0MTQtZkcxaGNLbXZObk9xWWk3WTNGY24iLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwNDE0LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSA1LiBSRUQgVkVMVkVUIENMT1RIIChDb3JuZWxsIHJlZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRWZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDUsIDAuMDUsIDAuMDQsIDEuMCkgICMgZGVlcCBDb3JuZWxsIHJlZFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxuIyBWZWx2ZXQgc2hlZW4gdmlhIG5vaXNlXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBDbG90aCBidW1wIGZvciB3ZWF2ZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDYuIEdSRUVOIFZFTFZFVCBDTE9USCAoQ29ybmVsbCBncmVlbikgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNSwgMC4zMCwgMC4wNiwgMS4wKSAgIyBkZWVwIENvcm5lbGwgZ3JlZW5cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ1JlYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAobmV1dHJhbCBDb3JuZWxsIGVsZW1lbnQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fV2hpdGVMaW5lblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC43NSwgMC43MywgMC42OCwgMS4wKSAgIyB3YXJtIGdyZXktd2hpdGVcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjoxOTY4MSwiY29tcGxldGlvbl90b2tlbnMiOjE0MTAsInRvdGFsX3Rva2VucyI6MjEwOTEsImNvc3QiOjAuMDA3NzQ1Mzg3NjQsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MTk0NTYsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA3NzQ1Mzg3NjQsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDM1OTQ5MTE2NCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDA0MTUwNDc2fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 5. RED VELVET CLOTH (Cornell red) ---\nmat, nt = create_material(\"M_RedVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\n# Velvet sheen via noise\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Cloth bump for weave\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"RedCloth\"].data.materials.append(mat)\n\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\nmat, nt = create_material(\"M_GreenVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"GreenCloth\"].data.materials.append(mat)\n\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\nmat, nt = create_material(\"M_WhiteLinen\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\nbsdf.inputs['Roughness'].default_value = 0.9\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 20.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.5\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 150.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"WhiteCloth\"].data.materials.append(mat)\n\nprint(\"Cloth materials created.\")\nresult = {\"cloth_materials\": [\"M_RedVelvet\", \"M_GreenVelvet\", \"M_WhiteLinen\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}", "parse_error": null}], "tokens_in": 19681, "tokens_out": 1410, "cost_usd": 0.00774538764, "cached_tokens": 19456}, "error": null}
{"ts": "2026-07-17T15:00:50.348542+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 5. RED VELVET CLOTH (Cornell red) ---\nmat, nt = create_material(\"M_RedVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\n# Velvet sheen via noise\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Cloth bump for weave\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"RedCloth\"].data.materials.append(mat)\n\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\nmat, nt = create_material(\"M_GreenVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"GreenCloth\"].data.materials.append(mat)\n\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\nmat, nt = create_material(\"M_WhiteLinen\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\nbsdf.inputs['Roughness'].default_value = 0.9\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 20.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.5\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 150.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"WhiteCloth\"].data.materials.append(mat)\n\nprint(\"Cloth materials created.\")\nresult = {\"cloth_materials\": [\"M_RedVelvet\", \"M_GreenVelvet\", \"M_WhiteLinen\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:00:50.348542+00:00", "type": "tool_call", "id": "chatcmpl-tool-a837f3bf886e2bf3", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 5. RED VELVET CLOTH (Cornell red) ---\nmat, nt = create_material(\"M_RedVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\n# Velvet sheen via noise\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Cloth bump for weave\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"RedCloth\"].data.materials.append(mat)\n\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\nmat, nt = create_material(\"M_GreenVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"GreenCloth\"].data.materials.append(mat)\n\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\nmat, nt = create_material(\"M_WhiteLinen\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\nbsdf.inputs['Roughness'].default_value = 0.9\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 20.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.5\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 150.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"WhiteCloth\"].data.materials.append(mat)\n\nprint(\"Cloth materials created.\")\nresult = {\"cloth_materials\": [\"M_RedVelvet\", \"M_GreenVelvet\", \"M_WhiteLinen\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}
{"ts": "2026-07-17T15:00:51.422542+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "name": "execute_blender_code", "text": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:01:23.558988+00:00", "type": "llm_call", "call_index": 16, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:00:51.435458+00:00", "finished_at": "2026-07-17T15:01:23.558988+00:00", "duration_s": 32.125, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:00:51.435458+00:00", "finished_at": "2026-07-17T15:01:23.558988+00:00", "duration_s": 32.125, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "81363", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:00:53 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300452-yzX8tZH9aNThHPgZzAan", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1e61095333db-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300452-yzX8tZH9aNThHPgZzAan\",\"object\":\"chat.completion\",\"created\":1784300452,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":21223,\"completion_tokens\":1401,\"total_tokens\":22624,\"cost\":0.00901670172,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":19648,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00901670172,\"upstream_inference_prompt_cost\":0.00489271812,\"upstream_inference_completions_cost\":0.0041239836},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAwNDUyLXl6WDh0Wkg5YU5UaEhQZ1p6QWFuIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMDQ1MiwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBmaXggdGhhdCB0eXBvIOKAlCBJIHVzZWQgYFJlY2AgaW5zdGVhZCBvZiBgRmFjYC4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtODVmYjgyYWZmNGY3YmM5MSIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSA1LiBSRUQgVkVMVkVUIENMT1RIIChDb3JuZWxsIHJlZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRWZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDUsIDAuMDUsIDAuMDQsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDYuIEdSRUVOIFZFTFZFVCBDTE9USCAoQ29ybmVsbCBncmVlbikgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNSwgMC4zMCwgMC4wNiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pICAjIEZpeGVkOiAnRmFjJyBub3QgJ1JlYydcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9XaGl0ZUxpbmVuXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjc1LCAwLjczLCAwLjY4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MjEyMjMsImNvbXBsZXRpb25fdG9rZW5zIjoxNDAxLCJ0b3RhbF90b2tlbnMiOjIyNjI0LCJjb3N0IjowLjAwOTAxNjcwMTcyLCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjE5NjQ4LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwOTAxNjcwMTcyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA0ODkyNzE4MTIsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwNDEyMzk4MzZ9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 5. RED VELVET CLOTH (Cornell red) ---\nmat, nt = create_material(\"M_RedVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"RedCloth\"].data.materials.append(mat)\n\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\nmat, nt = create_material(\"M_GreenVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"GreenCloth\"].data.materials.append(mat)\n\n# --- 7. WHITE/GREY LINEN ---\nmat, nt = create_material(\"M_WhiteLinen\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 20.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.5\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 150.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"WhiteCloth\"].data.materials.append(mat)\n\nprint(\"Cloth materials created.\")\nresult = {\"cloth_materials\": [\"M_RedVelvet\", \"M_GreenVelvet\", \"M_WhiteLinen\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}", "parse_error": null}], "tokens_in": 21223, "tokens_out": 1401, "cost_usd": 0.00901670172, "cached_tokens": 19648}, "error": null}
{"ts": "2026-07-17T15:01:23.560996+00:00", "type": "assistant", "text": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 5. RED VELVET CLOTH (Cornell red) ---\nmat, nt = create_material(\"M_RedVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"RedCloth\"].data.materials.append(mat)\n\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\nmat, nt = create_material(\"M_GreenVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"GreenCloth\"].data.materials.append(mat)\n\n# --- 7. WHITE/GREY LINEN ---\nmat, nt = create_material(\"M_WhiteLinen\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 20.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.5\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 150.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"WhiteCloth\"].data.materials.append(mat)\n\nprint(\"Cloth materials created.\")\nresult = {\"cloth_materials\": [\"M_RedVelvet\", \"M_GreenVelvet\", \"M_WhiteLinen\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:01:23.561995+00:00", "type": "tool_call", "id": "chatcmpl-tool-85fb82aff4f7bc91", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 5. RED VELVET CLOTH (Cornell red) ---\nmat, nt = create_material(\"M_RedVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"RedCloth\"].data.materials.append(mat)\n\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\nmat, nt = create_material(\"M_GreenVelvet\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.85\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 15.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 120.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"GreenCloth\"].data.materials.append(mat)\n\n# --- 7. WHITE/GREY LINEN ---\nmat, nt = create_material(\"M_WhiteLinen\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 20.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.5\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 150.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"WhiteCloth\"].data.materials.append(mat)\n\nprint(\"Cloth materials created.\")\nresult = {\"cloth_materials\": [\"M_RedVelvet\", \"M_GreenVelvet\", \"M_WhiteLinen\"]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}
{"ts": "2026-07-17T15:01:24.827360+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:02:09.751854+00:00", "type": "llm_call", "call_index": 17, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:01:24.827360+00:00", "finished_at": "2026-07-17T15:02:09.751854+00:00", "duration_s": 44.92200000002049, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:01:24.827360+00:00", "finished_at": "2026-07-17T15:02:09.751349+00:00", "duration_s": 44.92200000002049, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "86329", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:01:38 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300496-zwlUy2LHWCQ0y3ADachP", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca1f76ebc30146-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300496-zwlUy2LHWCQ0y3ADachP\",\"object\":\"chat.completion\",\"created\":1784300496,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":22688,\"completion_tokens\":1355,\"total_tokens\":24043,\"cost\":0.00908196936,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":21184,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00908196936,\"upstream_inference_prompt_cost\":0.00509339136,\"upstream_inference_completions_cost\":0.003988578},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA0OTYtendsVXkyTEhXQ1EweTNBRGFjaFAiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwNDk2LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSBlbnZpcm9ubWVudCBhbmQgcmVtYWluaW5nIHByb3AgbWF0ZXJpYWxzIOKAlCB3YWxscywgdGFibGUsIGZydWl0LCBnbGFzcywgYm9vay4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYjU1MmQ1MWFiMDU5YTZlOCIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSA4LiBCQUNLIFdBTEwgKGRhcmssIGFnZWQgcGxhc3RlcikgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9CYWNrV2FsbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4xMiwgMC4xMCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xMCwgMC4wOCwgMC4wNiwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjE2LCAwLjEzLCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAzMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQmFja1dhbGxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDkuIFJFRCBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjM1LCAwLjA0LCAwLjAzLCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRQYW5lbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTAuIEdSRUVOIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5QYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNCwgMC4yMiwgMC4wNSwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYgb2Jqc1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5QYW5lbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTEuIFRBQkxFIFRPUCAoYWdlZCB3b29kKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1RhYmxlVG9wXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjIwLCAwLjE0LCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjZcXG5cXG4jIFdvb2QgZ3JhaW5cXG53YXZlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4V2F2ZScsICgwLCAxMDApKVxcbndhdmUud2F2ZV90eXBlID0gJ0JBTkRTJ1xcbndhdmUuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAyLjBcXG53YXZlLmlucHV0c1snRGlzdG9ydGlvbiddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG53YXZlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjE1LCAwLjEwLCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMjUsIDAuMTgsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMlxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlVG9wXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFRhYmxlIGVkZ2UgYW5kIGZsb29yIHNoYXJlIHRhYmxlIG1hdGVyaWFsXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVFZGdlXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9UYWJsZVRvcFxcXCJdKVxcblxcbiMgLS0tIDEyLiBGTE9PUiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0Zsb29yXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA4LCAwLjA2LCAwLjA0LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJGbG9vclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkVudmlyb25tZW50IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjIyNjg4LCJjb21wbGV0aW9uX3Rva2VucyI6MTM1NSwidG90YWxfdG9rZW5zIjoyNDA0MywiY29zdCI6MC4wMDkwODE5NjkzNiwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjoyMTE4NCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDkwODE5NjkzNiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNTA5MzM5MTM2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDM5ODg1Nzh9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 8. BACK WALL (dark, aged plaster) ---\nmat, nt = create_material(\"M_BackWall\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 8.0\nnoise.inputs['Detail'].default_value = 6.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.3\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 30.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"BackWall\"].data.materials.append(mat)\n\n# --- 9. RED PANEL ---\nmat, nt = create_material(\"M_RedPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"RedPanel\"].data.materials.append(mat)\n\n# --- 10. GREEN PANEL ---\nmat, nt = create_material(\"M_GreenPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"GreenPanel\"].data.materials.append(mat)\n\n# --- 11. TABLE TOP (aged wood) ---\nmat, nt = create_material(\"M_TableTop\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.6\n\n# Wood grain\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\nwave.wave_type = 'BANDS'\nwave.inputs['Scale'].default_value = 2.0\nwave.inputs['Distortion'].default_value = 8.0\nwave.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.2\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"TableTop\"].data.materials.append(mat)\n\n# Table edge and floor share table material\nbpy.data.objects[\"TableEdge\"].data.materials.append(bpy.data.materials[\"M_TableTop\"])\n\n# --- 12. FLOOR ---\nmat, nt = create_material(\"M_Floor\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"Floor\"].data.materials.append(mat)\n\nprint(\"Environment materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 22688, "tokens_out": 1355, "cost_usd": 0.00908196936, "cached_tokens": 21184}, "error": null}
{"ts": "2026-07-17T15:02:09.753864+00:00", "type": "assistant", "text": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 8. BACK WALL (dark, aged plaster) ---\nmat, nt = create_material(\"M_BackWall\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 8.0\nnoise.inputs['Detail'].default_value = 6.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.3\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 30.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"BackWall\"].data.materials.append(mat)\n\n# --- 9. RED PANEL ---\nmat, nt = create_material(\"M_RedPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"RedPanel\"].data.materials.append(mat)\n\n# --- 10. GREEN PANEL ---\nmat, nt = create_material(\"M_GreenPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"GreenPanel\"].data.materials.append(mat)\n\n# --- 11. TABLE TOP (aged wood) ---\nmat, nt = create_material(\"M_TableTop\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.6\n\n# Wood grain\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\nwave.wave_type = 'BANDS'\nwave.inputs['Scale'].default_value = 2.0\nwave.inputs['Distortion'].default_value = 8.0\nwave.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.2\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"TableTop\"].data.materials.append(mat)\n\n# Table edge and floor share table material\nbpy.data.objects[\"TableEdge\"].data.materials.append(bpy.data.materials[\"M_TableTop\"])\n\n# --- 12. FLOOR ---\nmat, nt = create_material(\"M_Floor\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"Floor\"].data.materials.append(mat)\n\nprint(\"Environment materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:02:09.753864+00:00", "type": "tool_call", "id": "chatcmpl-tool-b552d51ab059a6e8", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 8. BACK WALL (dark, aged plaster) ---\nmat, nt = create_material(\"M_BackWall\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 8.0\nnoise.inputs['Detail'].default_value = 6.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.3\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 30.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"BackWall\"].data.materials.append(mat)\n\n# --- 9. RED PANEL ---\nmat, nt = create_material(\"M_RedPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"RedPanel\"].data.materials.append(mat)\n\n# --- 10. GREEN PANEL ---\nmat, nt = create_material(\"M_GreenPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"GreenPanel\"].data.materials.append(mat)\n\n# --- 11. TABLE TOP (aged wood) ---\nmat, nt = create_material(\"M_TableTop\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.6\n\n# Wood grain\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\nwave.wave_type = 'BANDS'\nwave.inputs['Scale'].default_value = 2.0\nwave.inputs['Distortion'].default_value = 8.0\nwave.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.2\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"TableTop\"].data.materials.append(mat)\n\n# Table edge and floor share table material\nbpy.data.objects[\"TableEdge\"].data.materials.append(bpy.data.materials[\"M_TableTop\"])\n\n# --- 12. FLOOR ---\nmat, nt = create_material(\"M_Floor\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"Floor\"].data.materials.append(mat)\n\nprint(\"Environment materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:02:11.294383+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "name": "execute_blender_code", "text": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:02:43.060828+00:00", "type": "llm_call", "call_index": 18, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:02:11.294383+00:00", "finished_at": "2026-07-17T15:02:43.060828+00:00", "duration_s": 31.76600000000326, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:02:11.294383+00:00", "finished_at": "2026-07-17T15:02:43.059830+00:00", "duration_s": 31.76600000000326, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "91652", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:02:13 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300532-u6RQ0SdlxnxNE8ddrlnW", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca20542efda6b0-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300532-u6RQ0SdlxnxNE8ddrlnW\",\"object\":\"chat.completion\",\"created\":1784300532,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":24191,\"completion_tokens\":1314,\"total_tokens\":25505,\"cost\":0.00924635604,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":22656,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00924635604,\"upstream_inference_prompt_cost\":0.00537846564,\"upstream_inference_completions_cost\":0.0038678904},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMDUzMi11NlJRMFNkbHhueE5FOGRkcmxuVyIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDA1MzIsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjoyNDE5MSwiY29tcGxldGlvbl90b2tlbnMiOjEzMTQsInRvdGFsX3Rva2VucyI6MjU1MDUsImNvc3QiOjAuMDA5MjQ2MzU2MDQsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MjI2NTYsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA5MjQ2MzU2MDQsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDUzNzg0NjU2NCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAzODY3ODkwNH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 8. BACK WALL ---\nmat, nt = create_material(\"M_BackWall\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 8.0\nnoise.inputs['Detail'].default_value = 6.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.3\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 30.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"BackWall\"].data.materials.append(mat)\n\n# --- 9. RED PANEL ---\nmat, nt = create_material(\"M_RedPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"RedPanel\"].data.materials.append(mat)\n\n# --- 10. GREEN PANEL ---\nmat, nt = create_material(\"M_GreenPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"GreenPanel\"].data.materials.append(mat)\n\n# --- 11. TABLE TOP ---\nmat, nt = create_material(\"M_TableTop\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.6\n\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\nwave.wave_type = 'BANDS'\nwave.inputs['Scale'].default_value = 2.0\nwave.inputs['Distortion'].default_value = 8.0\nwave.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.2\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"TableTop\"].data.materials.append(mat)\nbpy.data.objects[\"TableEdge\"].data.materials.append(bpy.data.materials[\"M_TableTop\"])\n\n# --- 12. FLOOR ---\nmat, nt = create_material(\"M_Floor\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"Floor\"].data.materials.append(mat)\n\nprint(\"Environment materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 24191, "tokens_out": 1314, "cost_usd": 0.00924635604, "cached_tokens": 22656}, "error": null}
{"ts": "2026-07-17T15:02:43.062940+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 8. BACK WALL ---\nmat, nt = create_material(\"M_BackWall\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 8.0\nnoise.inputs['Detail'].default_value = 6.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.3\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 30.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"BackWall\"].data.materials.append(mat)\n\n# --- 9. RED PANEL ---\nmat, nt = create_material(\"M_RedPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"RedPanel\"].data.materials.append(mat)\n\n# --- 10. GREEN PANEL ---\nmat, nt = create_material(\"M_GreenPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"GreenPanel\"].data.materials.append(mat)\n\n# --- 11. TABLE TOP ---\nmat, nt = create_material(\"M_TableTop\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.6\n\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\nwave.wave_type = 'BANDS'\nwave.inputs['Scale'].default_value = 2.0\nwave.inputs['Distortion'].default_value = 8.0\nwave.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.2\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"TableTop\"].data.materials.append(mat)\nbpy.data.objects[\"TableEdge\"].data.materials.append(bpy.data.materials[\"M_TableTop\"])\n\n# --- 12. FLOOR ---\nmat, nt = create_material(\"M_Floor\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"Floor\"].data.materials.append(mat)\n\nprint(\"Environment materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:02:43.062940+00:00", "type": "tool_call", "id": "chatcmpl-tool-ad7c6aebd182a662", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 8. BACK WALL ---\nmat, nt = create_material(\"M_BackWall\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 8.0\nnoise.inputs['Detail'].default_value = 6.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.3\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 30.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"BackWall\"].data.materials.append(mat)\n\n# --- 9. RED PANEL ---\nmat, nt = create_material(\"M_RedPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"RedPanel\"].data.materials.append(mat)\n\n# --- 10. GREEN PANEL ---\nmat, nt = create_material(\"M_GreenPanel\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"GreenPanel\"].data.materials.append(mat)\n\n# --- 11. TABLE TOP ---\nmat, nt = create_material(\"M_TableTop\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.6\n\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\nwave.wave_type = 'BANDS'\nwave.inputs['Scale'].default_value = 2.0\nwave.inputs['Distortion'].default_value = 8.0\nwave.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.2\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"TableTop\"].data.materials.append(mat)\nbpy.data.objects[\"TableEdge\"].data.materials.append(bpy.data.materials[\"M_TableTop\"])\n\n# --- 12. FLOOR ---\nmat, nt = create_material(\"M_Floor\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.9\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"Floor\"].data.materials.append(mat)\n\nprint(\"Environment materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:02:44.696759+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:03:12.015926+00:00", "type": "llm_call", "call_index": 19, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:02:44.697769+00:00", "finished_at": "2026-07-17T15:03:12.014419+00:00", "duration_s": 27.312999999994645, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:02:44.697769+00:00", "finished_at": "2026-07-17T15:03:12.014419+00:00", "duration_s": 27.312999999994645, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "96384", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:02:47 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300565-OPGQArEFKyreSvYuzV5K", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2124ef1280ee-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300565-OPGQArEFKyreSvYuzV5K\",\"object\":\"chat.completion\",\"created\":1784300565,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a15057346df8e108\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":25543,\"completion_tokens\":1053,\"total_tokens\":26596,\"cost\":0.00862172412,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":24128,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00862172412,\"upstream_inference_prompt_cost\":0.00552211332,\"upstream_inference_completions_cost\":0.0030996108},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA1NjUtT1BHUUFyRUZLeXJlU3ZZdXpWNUsiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwNTY1LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjoyNTU0MywiY29tcGxldGlvbl90b2tlbnMiOjEwNTMsInRvdGFsX3Rva2VucyI6MjY1OTYsImNvc3QiOjAuMDA4NjIxNzI0MTIsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MjQxMjgsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA4NjIxNzI0MTIsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDU1MjIxMTMzMiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAzMDk5NjEwOH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 13. WINE GLASS (glass with wine) ---\nmat, nt = create_material(\"M_WineGlass\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\nglass.inputs['Roughness'].default_value = 0.0\nglass.inputs['IOR'].default_value = 1.45\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"WineGlass\"].data.materials.append(mat)\n\n# --- 14. BOOK PAGES (aged paper) ---\nmat, nt = create_material(\"M_BookPages\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\nbsdf.inputs['Roughness'].default_value = 0.85\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"OpenBook\"].data.materials.append(mat)\n\n# --- 15. BOOK COVER (aged leather - dark) ---\nmat, nt = create_material(\"M_BookCover\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\nbsdf.inputs['Roughness'].default_value = 0.65\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"BookCover\"].data.materials.append(mat)\n\n# --- 16. ORANGES ---\nmat, nt = create_material(\"M_Orange\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\n\n# Orange peel texture\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.5\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise.inputs['Scale'].default_value = 60.0\nnoise.inputs['Detail'].default_value = 2.0\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nfor name in [\"Orange1\", \"Orange2\"]:\n    bpy.data.objects[name].data.materials.append(mat)\n\n# --- 17. LEMON ---\nmat, nt = create_material(\"M_Lemon\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise.inputs['Scale'].default_value = 80.0\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"Lemon1\"].data.materials.append(mat)\n\nprint(\"Prop materials created.\")\nresult = {\"status\": \"ok\", \"materials\": [m.name for m in bpy.data.materials]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}", "parse_error": null}], "tokens_in": 25543, "tokens_out": 1053, "cost_usd": 0.00862172412, "cached_tokens": 24128}, "error": null}
{"ts": "2026-07-17T15:03:12.018436+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 13. WINE GLASS (glass with wine) ---\nmat, nt = create_material(\"M_WineGlass\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\nglass.inputs['Roughness'].default_value = 0.0\nglass.inputs['IOR'].default_value = 1.45\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"WineGlass\"].data.materials.append(mat)\n\n# --- 14. BOOK PAGES (aged paper) ---\nmat, nt = create_material(\"M_BookPages\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\nbsdf.inputs['Roughness'].default_value = 0.85\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"OpenBook\"].data.materials.append(mat)\n\n# --- 15. BOOK COVER (aged leather - dark) ---\nmat, nt = create_material(\"M_BookCover\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\nbsdf.inputs['Roughness'].default_value = 0.65\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"BookCover\"].data.materials.append(mat)\n\n# --- 16. ORANGES ---\nmat, nt = create_material(\"M_Orange\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\n\n# Orange peel texture\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.5\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise.inputs['Scale'].default_value = 60.0\nnoise.inputs['Detail'].default_value = 2.0\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nfor name in [\"Orange1\", \"Orange2\"]:\n    bpy.data.objects[name].data.materials.append(mat)\n\n# --- 17. LEMON ---\nmat, nt = create_material(\"M_Lemon\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise.inputs['Scale'].default_value = 80.0\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"Lemon1\"].data.materials.append(mat)\n\nprint(\"Prop materials created.\")\nresult = {\"status\": \"ok\", \"materials\": [m.name for m in bpy.data.materials]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:03:12.018436+00:00", "type": "tool_call", "id": "chatcmpl-tool-a15057346df8e108", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- 13. WINE GLASS (glass with wine) ---\nmat, nt = create_material(\"M_WineGlass\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\nglass.inputs['Roughness'].default_value = 0.0\nglass.inputs['IOR'].default_value = 1.45\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"WineGlass\"].data.materials.append(mat)\n\n# --- 14. BOOK PAGES (aged paper) ---\nmat, nt = create_material(\"M_BookPages\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\nbsdf.inputs['Roughness'].default_value = 0.85\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"OpenBook\"].data.materials.append(mat)\n\n# --- 15. BOOK COVER (aged leather - dark) ---\nmat, nt = create_material(\"M_BookCover\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\nbsdf.inputs['Roughness'].default_value = 0.65\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"BookCover\"].data.materials.append(mat)\n\n# --- 16. ORANGES ---\nmat, nt = create_material(\"M_Orange\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\n\n# Orange peel texture\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.5\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise.inputs['Scale'].default_value = 60.0\nnoise.inputs['Detail'].default_value = 2.0\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nfor name in [\"Orange1\", \"Orange2\"]:\n    bpy.data.objects[name].data.materials.append(mat)\n\n# --- 17. LEMON ---\nmat, nt = create_material(\"M_Lemon\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise.inputs['Scale'].default_value = 80.0\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"Lemon1\"].data.materials.append(mat)\n\nprint(\"Prop materials created.\")\nresult = {\"status\": \"ok\", \"materials\": [m.name for m in bpy.data.materials]}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}
{"ts": "2026-07-17T15:03:12.111587+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "name": "execute_blender_code", "text": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:03:23.772923+00:00", "type": "llm_call", "call_index": 20, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:03:12.112597+00:00", "finished_at": "2026-07-17T15:03:23.772923+00:00", "duration_s": 11.655999999988126, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:03:12.112597+00:00", "finished_at": "2026-07-17T15:03:23.771923+00:00", "duration_s": 11.655999999988126, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "100698", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:03:14 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300592-vyCQBBWKNUFRWiUluWbs", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca21d03c40e074-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300592-vyCQBBWKNUFRWiUluWbs\",\"object\":\"chat.completion\",\"created\":1784300592,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":26728,\"completion_tokens\":389,\"total_tokens\":27117,\"cost\":0.00670321944,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":25536,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00670321944,\"upstream_inference_prompt_cost\":0.00555815904,\"upstream_inference_completions_cost\":0.0011450604},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAwNTkyLXZ5Q1FCQldLTlVGUldpVWx1V2JzIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMDU5MiwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWIyOWEyZmU1YzQxMWQ1YTgiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbiMgRml4IGxlbW9uIG1hdGVyaWFsIC0gdGhlIG5vaXNlIG91dHB1dCBzaG91bGQgYmUgJ0ZhYycgbm90ICdCJ1xcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fTGVtb25cXFwiKVxcbmlmIG1hdDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShtYXQpXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyBSZS1jcmVhdGUgbGVtb24gd2l0aCBjb3JyZWN0IG91dHB1dFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pICAjIEZpeGVkOiAnRmFjJ1xcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MjY3MjgsImNvbXBsZXRpb25fdG9rZW5zIjozODksInRvdGFsX3Rva2VucyI6MjcxMTcsImNvc3QiOjAuMDA2NzAzMjE5NDQsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MjU1MzYsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA2NzAzMjE5NDQsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDU1NTgxNTkwNCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAxMTQ1MDYwNH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Fix lemon material - the noise output should be 'Fac' not 'B'\nmat = bpy.data.materials.get(\"M_Lemon\")\nif mat:\n    bpy.data.materials.remove(mat)\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# Re-create lemon with correct output\nmat, nt = create_material(\"M_Lemon\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise.inputs['Scale'].default_value = 80.0\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"Lemon1\"].data.materials.append(mat)\n\nprint(\"Lemon material fixed.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 26728, "tokens_out": 389, "cost_usd": 0.00670321944, "cached_tokens": 25536}, "error": null}
{"ts": "2026-07-17T15:03:23.774979+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Fix lemon material - the noise output should be 'Fac' not 'B'\nmat = bpy.data.materials.get(\"M_Lemon\")\nif mat:\n    bpy.data.materials.remove(mat)\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# Re-create lemon with correct output\nmat, nt = create_material(\"M_Lemon\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise.inputs['Scale'].default_value = 80.0\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"Lemon1\"].data.materials.append(mat)\n\nprint(\"Lemon material fixed.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:03:23.774979+00:00", "type": "tool_call", "id": "chatcmpl-tool-b29a2fe5c411d5a8", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Fix lemon material - the noise output should be 'Fac' not 'B'\nmat = bpy.data.materials.get(\"M_Lemon\")\nif mat:\n    bpy.data.materials.remove(mat)\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# Re-create lemon with correct output\nmat, nt = create_material(\"M_Lemon\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.7\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.4\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise.inputs['Scale'].default_value = 80.0\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"Lemon1\"].data.materials.append(mat)\n\nprint(\"Lemon material fixed.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:03:24.503137+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:03:42.091923+00:00", "type": "llm_call", "call_index": 21, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:03:24.504144+00:00", "finished_at": "2026-07-17T15:03:42.090925+00:00", "duration_s": 17.59399999998277, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:03:24.504144+00:00", "finished_at": "2026-07-17T15:03:42.090925+00:00", "duration_s": 17.59399999998277, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "102468", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:03:26 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300605-1zmJcJXIbzQZDrLPeHy0", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca221dc976f4ac-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300605-1zmJcJXIbzQZDrLPeHy0\",\"object\":\"chat.completion\",\"created\":1784300605,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":27156,\"completion_tokens\":623,\"total_tokens\":27779,\"cost\":0.00691430232,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":26688,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00691430232,\"upstream_inference_prompt_cost\":0.00508043952,\"upstream_inference_completions_cost\":0.0018338628},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA2MDUtMXptSmNKWElielFaRHJMUGVIeTAiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwNjA1LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MjcxNTYsImNvbXBsZXRpb25fdG9rZW5zIjo2MjMsInRvdGFsX3Rva2VucyI6Mjc3NzksImNvc3QiOjAuMDA2OTE0MzAyMzIsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MjY2ODgsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA2OTE0MzAyMzIsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDUwODA0Mzk1MiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAxODMzODYyOH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\n# ============================================================\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\n# ============================================================\n\n# --- Key light: warm window shaft from the left ---\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\nkey_light = bpy.context.active_object\nkey_light.name = \"KeyLight_WarmShaft\"\nkey_light.data.energy = 800\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\nkey_light.data.size = 2.0\nkey_light.data.size_y = 3.5\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\n\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\nfill_light = bpy.context.active_object\nfill_light.name = \"FillLight_Cool\"\nfill_light.data.energy = 30\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\nfill_light.data.size = 3.0\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\n\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\nrim_light = bpy.context.active_object\nrim_light.name = \"RimLight\"\nrim_light.data.energy = 100\nrim_light.data.color = (1.0, 0.8, 0.5)\nrim_light.data.spot_size = math.radians(60)\nrim_light.data.spot_blend = 0.8\nrim_light.rotation_euler = (math.radians(120), 0, 0)\n\n# --- Window frame light (creates the shaft pattern) ---\n# A narrow area light to simulate light coming through a window\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\nwindow_light = bpy.context.active_object\nwindow_light.name = \"WindowLight\"\nwindow_light.data.energy = 400\nwindow_light.data.color = (1.0, 0.88, 0.65)\nwindow_light.data.size = 0.8\nwindow_light.data.size_y = 1.5\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\n\nprint(\"Lighting set up.\")\nresult = {\"lights\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}", "parse_error": null}], "tokens_in": 27156, "tokens_out": 623, "cost_usd": 0.00691430232, "cached_tokens": 26688}, "error": null}
{"ts": "2026-07-17T15:03:42.093926+00:00", "type": "assistant", "text": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\n# ============================================================\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\n# ============================================================\n\n# --- Key light: warm window shaft from the left ---\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\nkey_light = bpy.context.active_object\nkey_light.name = \"KeyLight_WarmShaft\"\nkey_light.data.energy = 800\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\nkey_light.data.size = 2.0\nkey_light.data.size_y = 3.5\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\n\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\nfill_light = bpy.context.active_object\nfill_light.name = \"FillLight_Cool\"\nfill_light.data.energy = 30\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\nfill_light.data.size = 3.0\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\n\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\nrim_light = bpy.context.active_object\nrim_light.name = \"RimLight\"\nrim_light.data.energy = 100\nrim_light.data.color = (1.0, 0.8, 0.5)\nrim_light.data.spot_size = math.radians(60)\nrim_light.data.spot_blend = 0.8\nrim_light.rotation_euler = (math.radians(120), 0, 0)\n\n# --- Window frame light (creates the shaft pattern) ---\n# A narrow area light to simulate light coming through a window\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\nwindow_light = bpy.context.active_object\nwindow_light.name = \"WindowLight\"\nwindow_light.data.energy = 400\nwindow_light.data.color = (1.0, 0.88, 0.65)\nwindow_light.data.size = 0.8\nwindow_light.data.size_y = 1.5\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\n\nprint(\"Lighting set up.\")\nresult = {\"lights\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:03:42.093926+00:00", "type": "tool_call", "id": "chatcmpl-tool-b0d781dd9dc96405", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\n# ============================================================\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\n# ============================================================\n\n# --- Key light: warm window shaft from the left ---\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\nkey_light = bpy.context.active_object\nkey_light.name = \"KeyLight_WarmShaft\"\nkey_light.data.energy = 800\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\nkey_light.data.size = 2.0\nkey_light.data.size_y = 3.5\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\n\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\nfill_light = bpy.context.active_object\nfill_light.name = \"FillLight_Cool\"\nfill_light.data.energy = 30\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\nfill_light.data.size = 3.0\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\n\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\nrim_light = bpy.context.active_object\nrim_light.name = \"RimLight\"\nrim_light.data.energy = 100\nrim_light.data.color = (1.0, 0.8, 0.5)\nrim_light.data.spot_size = math.radians(60)\nrim_light.data.spot_blend = 0.8\nrim_light.rotation_euler = (math.radians(120), 0, 0)\n\n# --- Window frame light (creates the shaft pattern) ---\n# A narrow area light to simulate light coming through a window\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\nwindow_light = bpy.context.active_object\nwindow_light.name = \"WindowLight\"\nwindow_light.data.energy = 400\nwindow_light.data.color = (1.0, 0.88, 0.65)\nwindow_light.data.size = 0.8\nwindow_light.data.size_y = 1.5\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\n\nprint(\"Lighting set up.\")\nresult = {\"lights\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}
{"ts": "2026-07-17T15:03:42.886397+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:03:53.877184+00:00", "type": "llm_call", "call_index": 22, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:03:42.887403+00:00", "finished_at": "2026-07-17T15:03:53.877184+00:00", "duration_s": 10.984000000025844, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:03:42.887403+00:00", "finished_at": "2026-07-17T15:03:53.875675+00:00", "duration_s": 10.984000000025844, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "105217", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:03:45 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300623-UG3MFJxgr9QTq1cYVvm3", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2290aa74031c-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300623-UG3MFJxgr9QTq1cYVvm3\",\"object\":\"chat.completion\",\"created\":1784300623,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":27845,\"completion_tokens\":360,\"total_tokens\":28205,\"cost\":0.00644378124,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":27136,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00644378124,\"upstream_inference_prompt_cost\":0.00538408524,\"upstream_inference_completions_cost\":0.001059696},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA2MjMtVUczTUZKeGdyOVFUcTFjWVZ2bTMiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwNjIzLCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGNhbWVyYSBhdCB0aGUgaW50aW1hdGUgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUgb2YgdGhlIGdlbnJlLCByb3VnaGx5IDUwbW0gZXF1aXZhbGVudC4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENBTUVSQTogfjUwbW0gZXF1aXZhbGVudCwgc2xpZ2h0bHkgZWxldmF0ZWQgaW50aW1hdGUgYW5nbGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMub2JqZWN0LmNhbWVyYV9hZGQobG9jYXRpb249KDMuMiwgLTMuOCwgMi4yKSlcXG5jYW0gPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuY2FtLm5hbWUgPSBcXFwiQ2FtZXJhX1ByZXNlbnRhdGlvblxcXCJcXG5jYW0uZGF0YS5sZW5zID0gNTAgICMgNTBtbSBmb2NhbCBsZW5ndGhcXG5jYW0uZGF0YS5zZW5zb3Jfd2lkdGggPSAzNiAgIyBmdWxsIGZyYW1lXFxuY2FtLmRhdGEuc2Vuc29yX2hlaWdodCA9IDM2ICAjIHNxdWFyZSBmb3JtYXQgZm9yIDE1MzZ4MTUzNlxcblxcbiMgUG9pbnQgY2FtZXJhIGF0IHRoZSB0ZWFwb3QgKGNlbnRlciBvZiBhcnJhbmdlbWVudClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMSwgMC40KSkgICMgc2xpZ2h0bHkgYWJvdmUgdGFibGUsIGF0IHRlYXBvdCBoZWlnaHRcXG5kaXJlY3Rpb24gPSB0YXJnZXQgLSBjYW0ubG9jYXRpb25cXG4jIENvbnZlcnQgZGlyZWN0aW9uIHRvIHJvdGF0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcblxcbiMgU2V0IGFzIGFjdGl2ZSBzY2VuZSBjYW1lcmFcXG5icHkuY29udGV4dC5zY2VuZS5jYW1lcmEgPSBjYW1cXG5cXG4jIERlcHRoIG9mIGZpZWxkIC0gc3VidGxlLCBmb2N1c2VkIG9uIHRlYXBvdFxcbmNhbS5kYXRhLmRvZi51c2VfZG9mID0gVHJ1ZVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcbmNhbS5kYXRhLmRvZi5hcGVydHVyZV9mc3RvcCA9IDQuMFxcblxcbnByaW50KFxcXCJDYW1lcmEgc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcbiAgICBcXFwiY2FtZXJhX2xvY2F0aW9uXFxcIjogbGlzdChjYW0ubG9jYXRpb24pLFxcbiAgICBcXFwiY2FtZXJhX3JvdGF0aW9uXFxcIjogW21hdGguZGVncmVlcyhyKSBmb3IgciBpbiBjYW0ucm90YXRpb25fZXVsZXJdLFxcbiAgICBcXFwibGVuc1xcXCI6IGNhbS5kYXRhLmxlbnMsXFxuICAgIFxcXCJmb2N1c19kaXN0YW5jZVxcXCI6IGNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZVxcbn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjoyNzg0NSwiY29tcGxldGlvbl90b2tlbnMiOjM2MCwidG90YWxfdG9rZW5zIjoyODIwNSwiY29zdCI6MC4wMDY0NDM3ODEyNCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjoyNzEzNiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDY0NDM3ODEyNCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNTM4NDA4NTI0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDEwNTk2OTZ9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\n# ============================================================\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\ncam = bpy.context.active_object\ncam.name = \"Camera_Presentation\"\ncam.data.lens = 50  # 50mm focal length\ncam.data.sensor_width = 36  # full frame\ncam.data.sensor_height = 36  # square format for 1536x1536\n\n# Point camera at the teapot (center of arrangement)\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\ndirection = target - cam.location\n# Convert direction to rotation\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\n\n# Set as active scene camera\nbpy.context.scene.camera = cam\n\n# Depth of field - subtle, focused on teapot\ncam.data.dof.use_dof = True\ncam.data.dof.focus_distance = (cam.location - target).length\ncam.data.dof.aperture_fstop = 4.0\n\nprint(\"Camera set up.\")\nresult = {\n    \"camera_location\": list(cam.location),\n    \"camera_rotation\": [math.degrees(r) for r in cam.rotation_euler],\n    \"lens\": cam.data.lens,\n    \"focus_distance\": cam.data.dof.focus_distance\n}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}", "parse_error": null}], "tokens_in": 27845, "tokens_out": 360, "cost_usd": 0.00644378124, "cached_tokens": 27136}, "error": null}
{"ts": "2026-07-17T15:03:53.879191+00:00", "type": "assistant", "text": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\n# ============================================================\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\ncam = bpy.context.active_object\ncam.name = \"Camera_Presentation\"\ncam.data.lens = 50  # 50mm focal length\ncam.data.sensor_width = 36  # full frame\ncam.data.sensor_height = 36  # square format for 1536x1536\n\n# Point camera at the teapot (center of arrangement)\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\ndirection = target - cam.location\n# Convert direction to rotation\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\n\n# Set as active scene camera\nbpy.context.scene.camera = cam\n\n# Depth of field - subtle, focused on teapot\ncam.data.dof.use_dof = True\ncam.data.dof.focus_distance = (cam.location - target).length\ncam.data.dof.aperture_fstop = 4.0\n\nprint(\"Camera set up.\")\nresult = {\n    \"camera_location\": list(cam.location),\n    \"camera_rotation\": [math.degrees(r) for r in cam.rotation_euler],\n    \"lens\": cam.data.lens,\n    \"focus_distance\": cam.data.dof.focus_distance\n}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:03:53.879191+00:00", "type": "tool_call", "id": "chatcmpl-tool-81d514f5f212c1fe", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\n# ============================================================\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\ncam = bpy.context.active_object\ncam.name = \"Camera_Presentation\"\ncam.data.lens = 50  # 50mm focal length\ncam.data.sensor_width = 36  # full frame\ncam.data.sensor_height = 36  # square format for 1536x1536\n\n# Point camera at the teapot (center of arrangement)\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\ndirection = target - cam.location\n# Convert direction to rotation\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\n\n# Set as active scene camera\nbpy.context.scene.camera = cam\n\n# Depth of field - subtle, focused on teapot\ncam.data.dof.use_dof = True\ncam.data.dof.focus_distance = (cam.location - target).length\ncam.data.dof.aperture_fstop = 4.0\n\nprint(\"Camera set up.\")\nresult = {\n    \"camera_location\": list(cam.location),\n    \"camera_rotation\": [math.degrees(r) for r in cam.rotation_euler],\n    \"lens\": cam.data.lens,\n    \"focus_distance\": cam.data.dof.focus_distance\n}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}
{"ts": "2026-07-17T15:03:54.272411+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:03:57.602471+00:00", "type": "llm_call", "call_index": 23, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:03:54.272411+00:00", "finished_at": "2026-07-17T15:03:57.602471+00:00", "duration_s": 3.3280000000086147, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:03:54.272411+00:00", "finished_at": "2026-07-17T15:03:57.601471+00:00", "duration_s": 3.3280000000086147, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "107316", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:03:56 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300635-XNPM3W2NvcpiJREoCIpK", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca22d7b99bcfce-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300635-XNPM3W2NvcpiJREoCIpK\",\"object\":\"chat.completion\",\"created\":1784300635,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-80a032b133fec618\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":28366,\"completion_tokens\":41,\"total_tokens\":28407,\"cost\":0.0054558288,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":27840,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0054558288,\"upstream_inference_prompt_cost\":0.0053351412,\"upstream_inference_completions_cost\":0.0001206876},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA2MzUtWE5QTTNXMk52Y3BpSlJFb0NJcEsiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwNjM1LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjI4MzY2LCJjb21wbGV0aW9uX3Rva2VucyI6NDEsInRvdGFsX3Rva2VucyI6Mjg0MDcsImNvc3QiOjAuMDA1NDU1ODI4OCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjoyNzg0MCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDU0NTU4Mjg4LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA1MzM1MTQxMiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAwMTIwNjg3Nn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "name": "render_thumbnail_to_path", "arguments": {"output_path": "C:/tmp/still_life_preview1.png"}, "raw_arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}", "parse_error": null}], "tokens_in": 28366, "tokens_out": 41, "cost_usd": 0.0054558288, "cached_tokens": 27840}, "error": null}
{"ts": "2026-07-17T15:03:57.604469+00:00", "type": "assistant", "text": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "name": "render_thumbnail_to_path", "arguments": {"output_path": "C:/tmp/still_life_preview1.png"}, "raw_arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:03:57.604469+00:00", "type": "tool_call", "id": "chatcmpl-tool-80a032b133fec618", "name": "render_thumbnail_to_path", "arguments": {"output_path": "C:/tmp/still_life_preview1.png"}, "raw_arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}
{"ts": "2026-07-17T15:05:26.539216+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "name": "render_thumbnail_to_path", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:05:29.349074+00:00", "type": "llm_call", "call_index": 24, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:05:26.540216+00:00", "finished_at": "2026-07-17T15:05:29.349074+00:00", "duration_s": 2.812999999994645, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:05:26.540216+00:00", "finished_at": "2026-07-17T15:05:29.348064+00:00", "duration_s": 2.812999999994645, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "107892", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:05:29 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300727-m3xvQjD5z1HATcNJDGUJ", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca25189d9a3eaf-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300727-m3xvQjD5z1HATcNJDGUJ\",\"object\":\"chat.completion\",\"created\":1784300727,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-91107c27573cb421\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":28471,\"completion_tokens\":22,\"total_tokens\":28493,\"cost\":0.00510776148,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":28352,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00510776148,\"upstream_inference_prompt_cost\":0.00504300228,\"upstream_inference_completions_cost\":0.0000647592},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMDcyNy1tM3h2UWpENXoxSEFUY05KREdVSiIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDA3MjcsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC05MTEwN2MyNzU3M2NiNDIxIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6Mjg0NzEsImNvbXBsZXRpb25fdG9rZW5zIjoyMiwidG90YWxfdG9rZW5zIjoyODQ5MywiY29zdCI6MC4wMDUxMDc3NjE0OCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjoyODM1MiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDUxMDc3NjE0OCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNTA0MzAwMjI4LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDAwNjQ3NTkyfSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}], "tokens_in": 28471, "tokens_out": 22, "cost_usd": 0.00510776148, "cached_tokens": 28352}, "error": null}
{"ts": "2026-07-17T15:05:29.351132+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:05:29.351132+00:00", "type": "tool_call", "id": "chatcmpl-tool-91107c27573cb421", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}
{"ts": "2026-07-17T15:05:29.669118+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "name": "get_screenshot_of_area_as_image", "text": "", "is_error": false, "has_image": true, "image_b64": "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"}
{"ts": "2026-07-17T15:05:37.559728+00:00", "type": "llm_call", "call_index": 25, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:05:29.672631+00:00", "finished_at": "2026-07-17T15:05:37.557809+00:00", "duration_s": 7.89100000000326, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:05:29.672631+00:00", "finished_at": "2026-07-17T15:05:37.557809+00:00", "duration_s": 7.89100000000326, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "108178", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:05:33 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300730-dWaPhL01SFz8VnmI61q8", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca252c1be4b6ba-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300730-dWaPhL01SFz8VnmI61q8\",\"object\":\"chat.completion\",\"created\":1784300730,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":28497,\"completion_tokens\":155,\"total_tokens\":28652,\"cost\":0.00547480164,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":28416,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00547480164,\"upstream_inference_prompt_cost\":0.00501854364,\"upstream_inference_completions_cost\":0.000456258},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAwNzMwLWRXYVBoTDAxU0Z6OFZubUk2MXE4Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMDczMCwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjI4NDk3LCJjb21wbGV0aW9uX3Rva2VucyI6MTU1LCJ0b3RhbF90b2tlbnMiOjI4NjUyLCJjb3N0IjowLjAwNTQ3NDgwMTY0LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjI4NDE2LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwNTQ3NDgwMTY0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA1MDE4NTQzNjQsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMDQ1NjI1OH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n# Check what the render output looks like by examining the image\nimg = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\")\nprint(f\"Image size: {img.size[0]}x{img.size[1]}\")\nprint(f\"Image channels: {img.channels}\")\n# Get some pixel values to check if it's rendering properly\npixels = list(img.pixels[:20])\nprint(f\"First pixels: {pixels}\")\nresult = {\"image_size\": list(img.size), \"loaded\": True}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}", "parse_error": null}], "tokens_in": 28497, "tokens_out": 155, "cost_usd": 0.00547480164, "cached_tokens": 28416}, "error": null}
{"ts": "2026-07-17T15:05:37.561737+00:00", "type": "assistant", "text": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n# Check what the render output looks like by examining the image\nimg = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\")\nprint(f\"Image size: {img.size[0]}x{img.size[1]}\")\nprint(f\"Image channels: {img.channels}\")\n# Get some pixel values to check if it's rendering properly\npixels = list(img.pixels[:20])\nprint(f\"First pixels: {pixels}\")\nresult = {\"image_size\": list(img.size), \"loaded\": True}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:05:37.561737+00:00", "type": "tool_call", "id": "chatcmpl-tool-97c7b5546a1ad792", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n# Check what the render output looks like by examining the image\nimg = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\")\nprint(f\"Image size: {img.size[0]}x{img.size[1]}\")\nprint(f\"Image channels: {img.channels}\")\n# Get some pixel values to check if it's rendering properly\npixels = list(img.pixels[:20])\nprint(f\"First pixels: {pixels}\")\nresult = {\"image_size\": list(img.size), \"loaded\": True}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}
{"ts": "2026-07-17T15:05:37.814646+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:05:40.180963+00:00", "type": "llm_call", "call_index": 26, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:05:37.815652+00:00", "finished_at": "2026-07-17T15:05:40.179967+00:00", "duration_s": 2.3589999999967404, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:05:37.815652+00:00", "finished_at": "2026-07-17T15:05:40.178954+00:00", "duration_s": 2.3589999999967404, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "109602", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:05:40 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300738-6xGv17ZP8Esf2qkLR5aj", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca255f48333429-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300738-6xGv17ZP8Esf2qkLR5aj\",\"object\":\"chat.completion\",\"created\":1784300738,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]}}],\"usage\":{\"prompt_tokens\":28953,\"completion_tokens\":11,\"total_tokens\":28964,\"cost\":0.0054292026,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":28480,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0054292026,\"upstream_inference_prompt_cost\":0.005396823,\"upstream_inference_completions_cost\":0.0000323796},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA3MzgtNnhHdjE3WlA4RXNmMnFrTFI1YWoiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwNzM4LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6Mjg5NTMsImNvbXBsZXRpb25fdG9rZW5zIjoxMSwidG90YWxfdG9rZW5zIjoyODk2NCwiY29zdCI6MC4wMDU0MjkyMDI2LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjI4NDgwLCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwNTQyOTIwMjYsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDUzOTY4MjMsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMDAzMjM3OTZ9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "name": "get_screenshot_of_window_as_json", "arguments": {}, "raw_arguments": "{}", "parse_error": null}], "tokens_in": 28953, "tokens_out": 11, "cost_usd": 0.0054292026, "cached_tokens": 28480}, "error": null}
{"ts": "2026-07-17T15:05:40.182961+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "name": "get_screenshot_of_window_as_json", "arguments": {}, "raw_arguments": "{}", "parse_error": null}]}
{"ts": "2026-07-17T15:05:40.182961+00:00", "type": "tool_call", "id": "chatcmpl-tool-a7524c48acac6867", "name": "get_screenshot_of_window_as_json", "arguments": {}, "raw_arguments": "{}"}
{"ts": "2026-07-17T15:05:40.305373+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "name": "get_screenshot_of_window_as_json", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:05:45.086583+00:00", "type": "llm_call", "call_index": 27, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:05:40.305373+00:00", "finished_at": "2026-07-17T15:05:45.085589+00:00", "duration_s": 4.780999999988126, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:05:40.305373+00:00", "finished_at": "2026-07-17T15:05:45.084574+00:00", "duration_s": 4.780999999988126, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "114900", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:05:42 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300741-Mn4cxWXc3XLZPHLMtpGj", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca256e8893cbb2-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300741-Mn4cxWXc3XLZPHLMtpGj\",\"object\":\"chat.completion\",\"created\":1784300741,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":30262,\"completion_tokens\":111,\"total_tokens\":30373,\"cost\":0.00660790032,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":28928,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00660790032,\"upstream_inference_prompt_cost\":0.00628116072,\"upstream_inference_completions_cost\":0.0003267396},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA3NDEtTW40Y3hXWGMzWExaUEhMTXRwR2oiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwNzQxLCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MzAyNjIsImNvbXBsZXRpb25fdG9rZW5zIjoxMTEsInRvdGFsX3Rva2VucyI6MzAzNzMsImNvc3QiOjAuMDA2NjA3OTAwMzIsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6Mjg5MjgsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA2NjA3OTAwMzIsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDYyODExNjA3MiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAwMzI2NzM5Nn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n# Set viewport to rendered mode to see the result\nfor area in bpy.context.screen.areas:\n    if area.type == 'VIEW_3D':\n        for space in area.spaces:\n            if space.type == 'VIEW_3D':\n                space.shading.type = 'RENDERED'\n                break\n        break\nprint(\"Set viewport to rendered\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 30262, "tokens_out": 111, "cost_usd": 0.00660790032, "cached_tokens": 28928}, "error": null}
{"ts": "2026-07-17T15:05:45.090092+00:00", "type": "assistant", "text": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n# Set viewport to rendered mode to see the result\nfor area in bpy.context.screen.areas:\n    if area.type == 'VIEW_3D':\n        for space in area.spaces:\n            if space.type == 'VIEW_3D':\n                space.shading.type = 'RENDERED'\n                break\n        break\nprint(\"Set viewport to rendered\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:05:45.090092+00:00", "type": "tool_call", "id": "chatcmpl-tool-8e4c646f6f5eaca4", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n# Set viewport to rendered mode to see the result\nfor area in bpy.context.screen.areas:\n    if area.type == 'VIEW_3D':\n        for space in area.spaces:\n            if space.type == 'VIEW_3D':\n                space.shading.type = 'RENDERED'\n                break\n        break\nprint(\"Set viewport to rendered\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:05:45.148376+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:05:49.197213+00:00", "type": "llm_call", "call_index": 28, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:05:45.148376+00:00", "finished_at": "2026-07-17T15:05:49.196208+00:00", "duration_s": 4.047000000020489, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:05:45.148376+00:00", "finished_at": "2026-07-17T15:05:49.196208+00:00", "duration_s": 4.047000000020489, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "115723", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:05:47 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300745-Iw1XRCCChwLexlYLWBgx", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca258ccb9dd591-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300745-Iw1XRCCChwLexlYLWBgx\",\"object\":\"chat.completion\",\"created\":1784300745,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":30411,\"completion_tokens\":22,\"total_tokens\":30433,\"cost\":0.00550926852,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":30208,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00550926852,\"upstream_inference_prompt_cost\":0.00544450932,\"upstream_inference_completions_cost\":0.0000647592},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA3NDUtSXcxWFJDQ0Nod0xleGxZTFdCZ3giLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwNzQ1LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtODc5YTAxYWYxNWIxZGE2NSIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjMwNDExLCJjb21wbGV0aW9uX3Rva2VucyI6MjIsInRvdGFsX3Rva2VucyI6MzA0MzMsImNvc3QiOjAuMDA1NTA5MjY4NTIsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MzAyMDgsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA1NTA5MjY4NTIsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDU0NDQ1MDkzMiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAwMDY0NzU5Mn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}], "tokens_in": 30411, "tokens_out": 22, "cost_usd": 0.00550926852, "cached_tokens": 30208}, "error": null}
{"ts": "2026-07-17T15:05:49.201726+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:05:49.201726+00:00", "type": "tool_call", "id": "chatcmpl-tool-879a01af15b1da65", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}
{"ts": "2026-07-17T15:05:49.877561+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "name": "get_screenshot_of_area_as_image", "text": "", "is_error": false, "has_image": true, "image_b64": "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"}
{"ts": "2026-07-17T15:06:04.401575+00:00", "type": "llm_call", "call_index": 29, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:05:49.880072+00:00", "finished_at": "2026-07-17T15:06:04.400573+00:00", "duration_s": 14.530999999988126, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:05:49.880072+00:00", "finished_at": "2026-07-17T15:06:04.400573+00:00", "duration_s": 14.530999999988126, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "116009", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:05:52 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300750-OeBh53flcukgetRhrKAs", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca25aa58d60ee5-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300750-OeBh53flcukgetRhrKAs\",\"object\":\"chat.completion\",\"created\":1784300750,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":30437,\"completion_tokens\":542,\"total_tokens\":30979,\"cost\":0.0069178614,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":30400,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0069178614,\"upstream_inference_prompt_cost\":0.0053224302,\"upstream_inference_completions_cost\":0.0015954312},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAwNzUwLU9lQmg1M2ZsY3VrZ2V0UmhyS0FzIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMDc1MCwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBleGFtaW5lIHRoZSByZW5kZXJlZCBwcmV2aWV3IG1vcmUgY2xvc2VseSBieSBzYW1wbGluZyBwaXhlbCB2YWx1ZXMgYWNyb3NzIHRoZSBpbWFnZSB0byB1bmRlcnN0YW5kIHRoZSBjb21wb3NpdGlvbi4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcbmlmIGltZyBpcyBOb25lOlxcbiAgICAjIExvYWQgdGhlIHJlbmRlcmVkIGltYWdlXFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxuXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG4jIFNhbXBsZSB2YXJpb3VzIHJlZ2lvbnMgb2YgdGhlIGltYWdlXFxuZGVmIHNhbXBsZV9yZWdpb24oeF9zdGFydCwgeV9zdGFydCwgeF9lbmQsIHlfZW5kLCBsYWJlbCk6XFxuICAgIHJfc3VtLCBnX3N1bSwgYl9zdW0sIGNvdW50ID0gMCwgMCwgMCwgMFxcbiAgICBmb3IgeSBpbiByYW5nZSh5X3N0YXJ0LCB5X2VuZCwgMTApOlxcbiAgICAgICAgZm9yIHggaW4gcmFuZ2UoeF9zdGFydCwgeF9lbmQsIDEwKTpcXG4gICAgICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgICAgICByX3N1bSArPSBwaXhlbHNbaWR4XVxcbiAgICAgICAgICAgIGdfc3VtICs9IHBpeGVsc1tpZHgrMV1cXG4gICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICByX2F2ZyA9IHJfc3VtIC8gY291bnQgaWYgY291bnQgPiAwIGVsc2UgMFxcbiAgICBnX2F2ZyA9IGdfc3VtIC8gY291bnQgaWYgY291bnQgPiAwIGVsc2UgMFxcbiAgICBiX2F2ZyA9IGJfc3VtIC8gY291bnQgaWYgY291bnQgPiAwIGVsc2UgMFxcbiAgICBwcmludChmXFxcIntsYWJlbH06IFI9e3JfYXZnOi4zZn0gRz17Z19hdmc6LjNmfSBCPXtiX2F2ZzouM2Z9XFxcIilcXG4gICAgcmV0dXJuIHJfYXZnLCBnX2F2ZywgYl9hdmdcXG5cXG4jIFNhbXBsZSBjZW50ZXIsIGNvcm5lcnMsIGFuZCByZWdpb25zXFxuc2FtcGxlX3JlZ2lvbigwLCAwLCB3Ly80LCBoLy80LCBcXFwiVG9wLWxlZnQgKGJnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbigzKncvLzQsIDMqaC8vNCwgdywgaCwgXFxcIkJvdHRvbS1yaWdodCAoZmcpXFxcIilcXG5zYW1wbGVfcmVnaW9uKHcvLzMsIGgvLzMsIDIqdy8vMywgMipoLy8zLCBcXFwiQ2VudGVyIChvYmplY3RzKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbigwLCAzKmgvLzQsIHcvLzQsIGgsIFxcXCJCb3R0b20tbGVmdFxcXCIpXFxuc2FtcGxlX3JlZ2lvbigzKncvLzQsIDAsIHcsIGgvLzQsIFxcXCJUb3AtcmlnaHRcXFwiKVxcblxcbiMgQ2hlY2sgb3ZlcmFsbCBicmlnaHRuZXNzXFxudG90YWxfYnJpZ2h0ID0gc3VtKHBpeGVsc1tpXSArIHBpeGVsc1tpKzFdICsgcGl4ZWxzW2krMl0gZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQqMTAwKSlcXG5wcmludChmXFxcIlxcXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZToge3RvdGFsX2JyaWdodCAvIChsZW4ocGl4ZWxzKS8vKDQqMTAwKSAqIDMpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjozMDQzNywiY29tcGxldGlvbl90b2tlbnMiOjU0MiwidG90YWxfdG9rZW5zIjozMDk3OSwiY29zdCI6MC4wMDY5MTc4NjE0LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjMwNDAwLCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwNjkxNzg2MTQsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDUzMjI0MzAyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDE1OTU0MzEyfSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nimg = bpy.data.images.get(\"still_life_preview1.png\")\nif img is None:\n    # Load the rendered image\n    img = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\")\n\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Sample various regions of the image\ndef sample_region(x_start, y_start, x_end, y_end, label):\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\n    for y in range(y_start, y_end, 10):\n        for x in range(x_start, x_end, 10):\n            idx = (y * w + x) * 4\n            r_sum += pixels[idx]\n            g_sum += pixels[idx+1]\n            b_sum += pixels[idx+2]\n            count += 1\n    r_avg = r_sum / count if count > 0 else 0\n    g_avg = g_sum / count if count > 0 else 0\n    b_avg = b_sum / count if count > 0 else 0\n    print(f\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\")\n    return r_avg, g_avg, b_avg\n\n# Sample center, corners, and regions\nsample_region(0, 0, w//4, h//4, \"Top-left (bg)\")\nsample_region(3*w//4, 3*h//4, w, h, \"Bottom-right (fg)\")\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \"Center (objects)\")\nsample_region(0, 3*h//4, w//4, h, \"Bottom-left\")\nsample_region(3*w//4, 0, w, h//4, \"Top-right\")\n\n# Check overall brightness\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\nprint(f\"\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 30437, "tokens_out": 542, "cost_usd": 0.0069178614, "cached_tokens": 30400}, "error": null}
{"ts": "2026-07-17T15:06:04.404272+00:00", "type": "assistant", "text": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nimg = bpy.data.images.get(\"still_life_preview1.png\")\nif img is None:\n    # Load the rendered image\n    img = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\")\n\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Sample various regions of the image\ndef sample_region(x_start, y_start, x_end, y_end, label):\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\n    for y in range(y_start, y_end, 10):\n        for x in range(x_start, x_end, 10):\n            idx = (y * w + x) * 4\n            r_sum += pixels[idx]\n            g_sum += pixels[idx+1]\n            b_sum += pixels[idx+2]\n            count += 1\n    r_avg = r_sum / count if count > 0 else 0\n    g_avg = g_sum / count if count > 0 else 0\n    b_avg = b_sum / count if count > 0 else 0\n    print(f\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\")\n    return r_avg, g_avg, b_avg\n\n# Sample center, corners, and regions\nsample_region(0, 0, w//4, h//4, \"Top-left (bg)\")\nsample_region(3*w//4, 3*h//4, w, h, \"Bottom-right (fg)\")\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \"Center (objects)\")\nsample_region(0, 3*h//4, w//4, h, \"Bottom-left\")\nsample_region(3*w//4, 0, w, h//4, \"Top-right\")\n\n# Check overall brightness\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\nprint(f\"\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:06:04.404272+00:00", "type": "tool_call", "id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nimg = bpy.data.images.get(\"still_life_preview1.png\")\nif img is None:\n    # Load the rendered image\n    img = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\")\n\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Sample various regions of the image\ndef sample_region(x_start, y_start, x_end, y_end, label):\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\n    for y in range(y_start, y_end, 10):\n        for x in range(x_start, x_end, 10):\n            idx = (y * w + x) * 4\n            r_sum += pixels[idx]\n            g_sum += pixels[idx+1]\n            b_sum += pixels[idx+2]\n            count += 1\n    r_avg = r_sum / count if count > 0 else 0\n    g_avg = g_sum / count if count > 0 else 0\n    b_avg = b_sum / count if count > 0 else 0\n    print(f\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\")\n    return r_avg, g_avg, b_avg\n\n# Sample center, corners, and regions\nsample_region(0, 0, w//4, h//4, \"Top-left (bg)\")\nsample_region(3*w//4, 3*h//4, w, h, \"Bottom-right (fg)\")\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \"Center (objects)\")\nsample_region(0, 3*h//4, w//4, h, \"Bottom-left\")\nsample_region(3*w//4, 0, w, h//4, \"Top-right\")\n\n# Check overall brightness\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\nprint(f\"\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:06:05.187151+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:06:11.015280+00:00", "type": "llm_call", "call_index": 30, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:06:05.187654+00:00", "finished_at": "2026-07-17T15:06:11.015280+00:00", "duration_s": 5.827999999979511, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:06:05.187654+00:00", "finished_at": "2026-07-17T15:06:11.015280+00:00", "duration_s": 5.827999999979511, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "118379", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:06:07 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300765-Y1DeeHBhzYPsO7GKuErQ", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca260a0e6603cb-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300765-Y1DeeHBhzYPsO7GKuErQ\",\"object\":\"chat.completion\",\"created\":1784300765,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"refusal\":null,\"reasoning\":\"The image is rendering. The top-right has green (G=0.411), the center has objects (R=0.518), and the bottom-left is dark (0.084). This seems like the composition is working. Let me do a proper render to see the full quality.\\n\\nLet me do a full-resolution render to a path and then view it.\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The image is rendering. The top-right has green (G=0.411), the center has objects (R=0.518), and the bottom-left is dark (0.084). This seems like the composition is working. Let me do a proper render to see the full quality.\\n\\nLet me do a full-resolution render to a path and then view it.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":31133,\"completion_tokens\":133,\"total_tokens\":31266,\"cost\":0.0063658026,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":30400,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0063658026,\"upstream_inference_prompt_cost\":0.0059743038,\"upstream_inference_completions_cost\":0.0003914988},\"completion_tokens_details\":{\"reasoning_tokens\":73,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA3NjUtWTFEZWVIQmh6WVBzTzdHS3VFclEiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwNzY1LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHJlbmRlciBpcyB3b3JraW5nLiBJIGNhbiBzZWUgdGhlIGdyZWVuIHBhbmVsIG9uIHRoZSByaWdodCBhbmQgb2JqZWN0cyBpbiB0aGUgY2VudGVyLiBMZXQgbWUgZG8gYSBwcm9wZXIgcmVuZGVyIHRvIGV2YWx1YXRlIHRoZSBmdWxsIGNvbXBvc2l0aW9uLiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6IlRoZSBpbWFnZSBpcyByZW5kZXJpbmcuIFRoZSB0b3AtcmlnaHQgaGFzIGdyZWVuIChHPTAuNDExKSwgdGhlIGNlbnRlciBoYXMgb2JqZWN0cyAoUj0wLjUxOCksIGFuZCB0aGUgYm90dG9tLWxlZnQgaXMgZGFyayAoMC4wODQpLiBUaGlzIHNlZW1zIGxpa2UgdGhlIGNvbXBvc2l0aW9uIGlzIHdvcmtpbmcuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gc2VlIHRoZSBmdWxsIHF1YWxpdHkuXG5cbkxldCBtZSBkbyBhIGZ1bGwtcmVzb2x1dGlvbiByZW5kZXIgdG8gYSBwYXRoIGFuZCB0aGVuIHZpZXcgaXQuIiwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC05MjE0ODA2MjhiZGQyYWNmIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiYXJndW1lbnRzIjoie1wib3V0cHV0X3BhdGhcIjogXCJDOi90bXAvc3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1wifSJ9fV0sInJlYXNvbmluZ19kZXRhaWxzIjpbeyJ0eXBlIjoicmVhc29uaW5nLnRleHQiLCJ0ZXh0IjoiVGhlIGltYWdlIGlzIHJlbmRlcmluZy4gVGhlIHRvcC1yaWdodCBoYXMgZ3JlZW4gKEc9MC40MTEpLCB0aGUgY2VudGVyIGhhcyBvYmplY3RzIChSPTAuNTE4KSwgYW5kIHRoZSBib3R0b20tbGVmdCBpcyBkYXJrICgwLjA4NCkuIFRoaXMgc2VlbXMgbGlrZSB0aGUgY29tcG9zaXRpb24gaXMgd29ya2luZy4gTGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBzZWUgdGhlIGZ1bGwgcXVhbGl0eS5cblxuTGV0IG1lIGRvIGEgZnVsbC1yZXNvbHV0aW9uIHJlbmRlciB0byBhIHBhdGggYW5kIHRoZW4gdmlldyBpdC4iLCJmb3JtYXQiOiJ1bmtub3duIiwiaW5kZXgiOjB9XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MzExMzMsImNvbXBsZXRpb25fdG9rZW5zIjoxMzMsInRvdGFsX3Rva2VucyI6MzEyNjYsImNvc3QiOjAuMDA2MzY1ODAyNiwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjozMDQwMCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDYzNjU4MDI2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA1OTc0MzAzOCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAwMzkxNDk4OH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6NzMsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "name": "render_viewport_to_path", "arguments": {"output_path": "C:/tmp/still_life_render1.png"}, "raw_arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}", "parse_error": null}], "tokens_in": 31133, "tokens_out": 133, "cost_usd": 0.0063658026, "cached_tokens": 30400}, "error": null}
{"ts": "2026-07-17T15:06:11.019310+00:00", "type": "assistant", "text": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "name": "render_viewport_to_path", "arguments": {"output_path": "C:/tmp/still_life_render1.png"}, "raw_arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:06:11.019310+00:00", "type": "tool_call", "id": "chatcmpl-tool-921480628bdd2acf", "name": "render_viewport_to_path", "arguments": {"output_path": "C:/tmp/still_life_render1.png"}, "raw_arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}
{"ts": "2026-07-17T15:07:39.762349+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "name": "render_viewport_to_path", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:08:08.320054+00:00", "type": "llm_call", "call_index": 31, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:07:39.778893+00:00", "finished_at": "2026-07-17T15:08:08.320054+00:00", "duration_s": 28.53200000000652, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:07:39.778893+00:00", "finished_at": "2026-07-17T15:08:08.320054+00:00", "duration_s": 28.53200000000652, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "119029", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:07:58 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300872-LXjjrhfSTYUMr52vwFrD", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca289f995e5874-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300872-LXjjrhfSTYUMr52vwFrD\",\"object\":\"chat.completion\",\"created\":1784300872,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":31253,\"completion_tokens\":410,\"total_tokens\":31663,\"cost\":0.00675665916,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":31104,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00675665916,\"upstream_inference_prompt_cost\":0.00554978316,\"upstream_inference_completions_cost\":0.001206876},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAwODcyLUxYampyaGZTVFlVTXI1MnZ3RnJEIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMDg3MiwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjMxMjUzLCJjb21wbGV0aW9uX3Rva2VucyI6NDEwLCJ0b3RhbF90b2tlbnMiOjMxNjYzLCJjb3N0IjowLjAwNjc1NjY1OTE2LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjMxMTA0LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwNjc1NjY1OTE2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA1NTQ5NzgzMTYsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMTIwNjg3Nn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimg = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Check more regions to understand composition\ndef sample_region(x_start, y_start, x_end, y_end, label):\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\n    for y in range(y_start, y_end, 10):\n        for x in range(x_start, x_end, 10):\n            idx = (y * w + x) * 4\n            if idx + 2 < len(pixels):\n                r_sum += pixels[idx]\n                g_sum += pixels[idx+1]\n                b_sum += pixels[idx+2]\n                count += 1\n    r_avg = r_sum / count if count > 0 else 0\n    g_avg = g_sum / count if count > 0 else 0\n    b_avg = b_sum / count if count > 0 else 0\n    print(f\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\")\n\n# Grid sampling\nfor gy in range(4):\n    for gx in range(4):\n        x1 = gx * w // 4\n        x2 = (gx+1) * w // 4\n        y1 = gy * h // 4\n        y2 = (gy+1) * h // 4\n        sample_region(x1, y1, x2, y2, f\"Grid[{gx},{gy}]\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 31253, "tokens_out": 410, "cost_usd": 0.00675665916, "cached_tokens": 31104}, "error": null}
{"ts": "2026-07-17T15:08:08.323565+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimg = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Check more regions to understand composition\ndef sample_region(x_start, y_start, x_end, y_end, label):\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\n    for y in range(y_start, y_end, 10):\n        for x in range(x_start, x_end, 10):\n            idx = (y * w + x) * 4\n            if idx + 2 < len(pixels):\n                r_sum += pixels[idx]\n                g_sum += pixels[idx+1]\n                b_sum += pixels[idx+2]\n                count += 1\n    r_avg = r_sum / count if count > 0 else 0\n    g_avg = g_sum / count if count > 0 else 0\n    b_avg = b_sum / count if count > 0 else 0\n    print(f\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\")\n\n# Grid sampling\nfor gy in range(4):\n    for gx in range(4):\n        x1 = gx * w // 4\n        x2 = (gx+1) * w // 4\n        y1 = gy * h // 4\n        y2 = (gy+1) * h // 4\n        sample_region(x1, y1, x2, y2, f\"Grid[{gx},{gy}]\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:08:08.323565+00:00", "type": "tool_call", "id": "chatcmpl-tool-af37df6737703d4f", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimg = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Check more regions to understand composition\ndef sample_region(x_start, y_start, x_end, y_end, label):\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\n    for y in range(y_start, y_end, 10):\n        for x in range(x_start, x_end, 10):\n            idx = (y * w + x) * 4\n            if idx + 2 < len(pixels):\n                r_sum += pixels[idx]\n                g_sum += pixels[idx+1]\n                b_sum += pixels[idx+2]\n                count += 1\n    r_avg = r_sum / count if count > 0 else 0\n    g_avg = g_sum / count if count > 0 else 0\n    b_avg = b_sum / count if count > 0 else 0\n    print(f\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\")\n\n# Grid sampling\nfor gy in range(4):\n    for gx in range(4):\n        x1 = gx * w // 4\n        x2 = (gx+1) * w // 4\n        y1 = gy * h // 4\n        y2 = (gy+1) * h // 4\n        sample_region(x1, y1, x2, y2, f\"Grid[{gx},{gy}]\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:08:09.094805+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:08:24.366213+00:00", "type": "llm_call", "call_index": 32, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:08:09.095309+00:00", "finished_at": "2026-07-17T15:08:24.365704+00:00", "duration_s": 15.26600000000326, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:08:09.095309+00:00", "finished_at": "2026-07-17T15:08:24.364571+00:00", "duration_s": 15.26600000000326, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "121462", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:08:11 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300889-6446bAK6JQSF5OImt4Yl", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca29107e520366-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300889-6446bAK6JQSF5OImt4Yl\",\"object\":\"chat.completion\",\"created\":1784300889,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":32183,\"completion_tokens\":517,\"total_tokens\":32700,\"cost\":0.00784504188,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":31232,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00784504188,\"upstream_inference_prompt_cost\":0.00632320068,\"upstream_inference_completions_cost\":0.0015218412},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMDg4OS02NDQ2YkFLNkpRU0Y1T0ltdDRZbCIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDA4ODksIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC05ZThkMWMzODQ0MTIwMjg5IiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbiMgTGV0IG1lIGFuYWx5emUgdGhlIGNvbXBvc2l0aW9uIG1vcmUgY2FyZWZ1bGx5XFxuIyBUaGUgZ3JpZCBzaG93czogbGVmdCBzaWRlIGhhcyB3YXJtIGxpZ2h0LCByaWdodCBzaWRlIGhhcyBncmVlbiwgY2VudGVyIGhhcyBvYmplY3RzXFxuIyBCb3R0b20tbGVmdCBpcyB2ZXJ5IGRhcmsgKGdvb2QgZm9yIGNoaWFyb3NjdXJvKVxcbiMgTGV0IG1lIGNoZWNrIGlmIG9iamVjdHMgYXJlIHZpc2libGUgYW5kIHdlbGwtcGxhY2VkXFxuXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcXFwiKVxcbmlmIGltZyBpcyBOb25lOlxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG4jIENoZWNrIGZvciB0aGUgdGVhcG90IGFyZWEgKHNob3VsZCBiZSBjZW50ZXItaXNoLCBicmlnaHQgY2VyYW1pYylcXG4jIENhbWVyYSBpcyBhdCAoMy4yLCAtMy44LCAyLjIpIGxvb2tpbmcgYXQgKC0wLjEsIDAuMSwgMC40KVxcbiMgVGVhcG90IGlzIGF0IHdvcmxkICgtMC4xLCAwLjEsIDApIC0gc2hvdWxkIGJlIHJvdWdobHkgY2VudGVyIG9mIGZyYW1lXFxuXFxuIyBMZXQgbWUgY2hlY2sgaWYgd2UgY2FuIHNlZSBicmlnaHQgaGlnaGxpZ2h0cyAoY2VyYW1pYyB0ZWFwb3QpXFxuYnJpZ2h0X2NvdW50ID0gMFxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIGlmIHIgPiAwLjggYW5kIGcgPiAwLjcgYW5kIGIgPiAwLjY6XFxuICAgICAgICBicmlnaHRfY291bnQgKz0gMVxcblxcbnByaW50KGZcXFwiQnJpZ2h0IGhpZ2hsaWdodCBwaXhlbHM6IHticmlnaHRfY291bnR9IC8ge2xlbihwaXhlbHMpLy80fSAoezEwMCpicmlnaHRfY291bnQvKGxlbihwaXhlbHMpLy80KTouMWZ9JSlcXFwiKVxcblxcbiMgQ2hlY2sgaWYgdGhlIHNwaGVyZSBpcyB2aXNpYmxlIChzaG91bGQgYmUgZGFyay9saWdodCBjaGVja2VyIHBhdHRlcm4pXFxuIyBDaGVjayBtaWRkbGUtYm90dG9tIGFyZWFcXG5taWRfYm90X2JyaWdodCA9IDBcXG5mb3IgeSBpbiByYW5nZShpbnQoaCowLjQpLCBpbnQoaCowLjYpKTpcXG4gICAgZm9yIHggaW4gcmFuZ2UoaW50KHcqMC40KSwgaW50KHcqMC42KSk6XFxuICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgIG1pZF9ib3RfYnJpZ2h0ICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG5wcmludChmXFxcIkNlbnRlciBicmlnaHRuZXNzIGF2Zzoge21pZF9ib3RfYnJpZ2h0IC8gKGludCh3KjAuMikgKiBpbnQoaCowLjIpKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCIsIFxcXCJicmlnaHRfcGl4ZWxzX3BjdFxcXCI6IDEwMCpicmlnaHRfY291bnQvKGxlbihwaXhlbHMpLy80KX1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjozMjE4MywiY29tcGxldGlvbl90b2tlbnMiOjUxNywidG90YWxfdG9rZW5zIjozMjcwMCwiY29zdCI6MC4wMDc4NDUwNDE4OCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjozMTIzMiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDc4NDUwNDE4OCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNjMyMzIwMDY4LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDE1MjE4NDEyfSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "name": "execute_blender_code", "arguments": {"code": "\n# Let me analyze the composition more carefully\n# The grid shows: left side has warm light, right side has green, center has objects\n# Bottom-left is very dark (good for chiaroscuro)\n# Let me check if objects are visible and well-placed\n\nimport bpy\nimg = bpy.data.images.get(\"still_life_render1.png\")\nif img is None:\n    img = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\")\n\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Check for the teapot area (should be center-ish, bright ceramic)\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\n\n# Let me check if we can see bright highlights (ceramic teapot)\nbright_count = 0\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    if r > 0.8 and g > 0.7 and b > 0.6:\n        bright_count += 1\n\nprint(f\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\")\n\n# Check if the sphere is visible (should be dark/light checker pattern)\n# Check middle-bottom area\nmid_bot_bright = 0\nfor y in range(int(h*0.4), int(h*0.6)):\n    for x in range(int(w*0.4), int(w*0.6)):\n        idx = (y * w + x) * 4\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\nprint(f\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\")\n\nresult = {\"status\": \"ok\", \"bright_pixels_pct\": 100*bright_count/(len(pixels)//4)}\n"}, "raw_arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}", "parse_error": null}], "tokens_in": 32183, "tokens_out": 517, "cost_usd": 0.00784504188, "cached_tokens": 31232}, "error": null}
{"ts": "2026-07-17T15:08:24.369222+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "name": "execute_blender_code", "arguments": {"code": "\n# Let me analyze the composition more carefully\n# The grid shows: left side has warm light, right side has green, center has objects\n# Bottom-left is very dark (good for chiaroscuro)\n# Let me check if objects are visible and well-placed\n\nimport bpy\nimg = bpy.data.images.get(\"still_life_render1.png\")\nif img is None:\n    img = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\")\n\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Check for the teapot area (should be center-ish, bright ceramic)\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\n\n# Let me check if we can see bright highlights (ceramic teapot)\nbright_count = 0\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    if r > 0.8 and g > 0.7 and b > 0.6:\n        bright_count += 1\n\nprint(f\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\")\n\n# Check if the sphere is visible (should be dark/light checker pattern)\n# Check middle-bottom area\nmid_bot_bright = 0\nfor y in range(int(h*0.4), int(h*0.6)):\n    for x in range(int(w*0.4), int(w*0.6)):\n        idx = (y * w + x) * 4\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\nprint(f\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\")\n\nresult = {\"status\": \"ok\", \"bright_pixels_pct\": 100*bright_count/(len(pixels)//4)}\n"}, "raw_arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:08:24.369222+00:00", "type": "tool_call", "id": "chatcmpl-tool-9e8d1c3844120289", "name": "execute_blender_code", "arguments": {"code": "\n# Let me analyze the composition more carefully\n# The grid shows: left side has warm light, right side has green, center has objects\n# Bottom-left is very dark (good for chiaroscuro)\n# Let me check if objects are visible and well-placed\n\nimport bpy\nimg = bpy.data.images.get(\"still_life_render1.png\")\nif img is None:\n    img = bpy.data.images.load(\"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\")\n\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Check for the teapot area (should be center-ish, bright ceramic)\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\n\n# Let me check if we can see bright highlights (ceramic teapot)\nbright_count = 0\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    if r > 0.8 and g > 0.7 and b > 0.6:\n        bright_count += 1\n\nprint(f\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\")\n\n# Check if the sphere is visible (should be dark/light checker pattern)\n# Check middle-bottom area\nmid_bot_bright = 0\nfor y in range(int(h*0.4), int(h*0.6)):\n    for x in range(int(w*0.4), int(w*0.6)):\n        idx = (y * w + x) * 4\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\nprint(f\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\")\n\nresult = {\"status\": \"ok\", \"bright_pixels_pct\": 100*bright_count/(len(pixels)//4)}\n"}, "raw_arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}
{"ts": "2026-07-17T15:08:25.886387+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:08:29.685414+00:00", "type": "llm_call", "call_index": 33, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:08:25.887386+00:00", "finished_at": "2026-07-17T15:08:29.685414+00:00", "duration_s": 3.797000000020489, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:08:25.887386+00:00", "finished_at": "2026-07-17T15:08:29.685414+00:00", "duration_s": 3.797000000020489, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "123634", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:08:28 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300906-oFdIDSsjqfpxx3ocbg89", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca29796f7d0d72-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300906-oFdIDSsjqfpxx3ocbg89\",\"object\":\"chat.completion\",\"created\":1784300906,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":32782,\"completion_tokens\":58,\"total_tokens\":32840,\"cost\":0.00637160952,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":32128,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00637160952,\"upstream_inference_prompt_cost\":0.00620088072,\"upstream_inference_completions_cost\":0.0001707288},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA5MDYtb0ZkSURTc2pxZnB4eDNvY2JnODkiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwOTA2LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHJlbmRlciBpcyB3b3JraW5nIHdlbGwuIEkgY2FuIHNlZSBicmlnaHQgaGlnaGxpZ2h0cyBmcm9tIHRoZSBjZXJhbWljIHRlYXBvdCBhbmQgb2JqZWN0cyBhcmUgdmlzaWJsZS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgcmVuZGVyZWQgaW1hZ2UgdG8gZXZhbHVhdGUgdGhlIGNvbXBvc2l0aW9uIHZpc3VhbGx5LiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC04YTQzNWNiYmY0ZDZkZGEwIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MzI3ODIsImNvbXBsZXRpb25fdG9rZW5zIjo1OCwidG90YWxfdG9rZW5zIjozMjg0MCwiY29zdCI6MC4wMDYzNzE2MDk1MiwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjozMjEyOCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDYzNzE2MDk1MiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNjIwMDg4MDcyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDAxNzA3Mjg4fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}], "tokens_in": 32782, "tokens_out": 58, "cost_usd": 0.00637160952, "cached_tokens": 32128}, "error": null}
{"ts": "2026-07-17T15:08:29.688936+00:00", "type": "assistant", "text": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:08:29.688936+00:00", "type": "tool_call", "id": "chatcmpl-tool-8a435cbbf4d6dda0", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}
{"ts": "2026-07-17T15:08:30.359270+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "name": "get_screenshot_of_area_as_image", "text": "", "is_error": false, "has_image": true, "image_b64": "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"}
{"ts": "2026-07-17T15:08:41.293190+00:00", "type": "llm_call", "call_index": 34, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:08:30.362781+00:00", "finished_at": "2026-07-17T15:08:41.292192+00:00", "duration_s": 10.937000000005355, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:08:30.362781+00:00", "finished_at": "2026-07-17T15:08:41.292192+00:00", "duration_s": 10.937000000005355, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "124105", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:08:32 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300911-5QSSk3yGhWIkXNSmFZbW", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca29955b2326b3-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300911-5QSSk3yGhWIkXNSmFZbW\",\"object\":\"chat.completion\",\"created\":1784300911,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"refusal\":null,\"reasoning\":\"Let me analyze the render data I have. The image shows:\\n- Top-left: dark (background wall)\\n- Top-right: green (green panel)\\n- Center: bright (objects, teapot ceramic)\\n- Bottom-left: very dark (shadow area)\\n- Bottom-right: bright (table edge in light)\\n\\nThe composition seems to be working. Let me now refine things based on what I can tell. The key issues I need to address:\\n\\n1. The bunny might need better positioning/material\\n2. The teapot needs to be more prominent as the hero\\n3. The checkered sphere needs to be more visible\\n4. The lighting might need adjustment for better chiaroscuro\\n5. The Cornell box palette (red vs green) needs to be stronger\\n\\nLet me check if there are any issues with the objects' placement and make refinements. Let me also make sure the bunny's remesh modifier is working properly.\\n\\nLet me do a more detailed check of the objects and then refine the composition.\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"Let me analyze the render data I have. The image shows:\\n- Top-left: dark (background wall)\\n- Top-right: green (green panel)\\n- Center: bright (objects, teapot ceramic)\\n- Bottom-left: very dark (shadow area)\\n- Bottom-right: bright (table edge in light)\\n\\nThe composition seems to be working. Let me now refine things based on what I can tell. The key issues I need to address:\\n\\n1. The bunny might need better positioning/material\\n2. The teapot needs to be more prominent as the hero\\n3. The checkered sphere needs to be more visible\\n4. The lighting might need adjustment for better chiaroscuro\\n5. The Cornell box palette (red vs green) needs to be stronger\\n\\nLet me check if there are any issues with the objects' placement and make refinements. Let me also make sure the bunny's remesh modifier is working properly.\\n\\nLet me do a more detailed check of the objects and then refine the composition.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":32844,\"completion_tokens\":341,\"total_tokens\":33185,\"cost\":0.00677461512,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":32768,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00677461512,\"upstream_inference_prompt_cost\":0.00577084752,\"upstream_inference_completions_cost\":0.0010037676},\"completion_tokens_details\":{\"reasoning_tokens\":228,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA5MTEtNVFTU2szeUdoV0lrWE5TbUZaYlciLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwOTExLCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGNoZWNrIHRoZSBtb2RpZmllciBzdGFjayBvbiB0aGUgYnVubnkgYW5kIHZlcmlmeSBhbGwgb2JqZWN0cyBhcmUgcmVuZGVyaW5nIHByb3Blcmx5LCB0aGVuIG1ha2UgcmVmaW5lbWVudHMuIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjoiTGV0IG1lIGFuYWx5emUgdGhlIHJlbmRlciBkYXRhIEkgaGF2ZS4gVGhlIGltYWdlIHNob3dzOlxuLSBUb3AtbGVmdDogZGFyayAoYmFja2dyb3VuZCB3YWxsKVxuLSBUb3AtcmlnaHQ6IGdyZWVuIChncmVlbiBwYW5lbClcbi0gQ2VudGVyOiBicmlnaHQgKG9iamVjdHMsIHRlYXBvdCBjZXJhbWljKVxuLSBCb3R0b20tbGVmdDogdmVyeSBkYXJrIChzaGFkb3cgYXJlYSlcbi0gQm90dG9tLXJpZ2h0OiBicmlnaHQgKHRhYmxlIGVkZ2UgaW4gbGlnaHQpXG5cblRoZSBjb21wb3NpdGlvbiBzZWVtcyB0byBiZSB3b3JraW5nLiBMZXQgbWUgbm93IHJlZmluZSB0aGluZ3MgYmFzZWQgb24gd2hhdCBJIGNhbiB0ZWxsLiBUaGUga2V5IGlzc3VlcyBJIG5lZWQgdG8gYWRkcmVzczpcblxuMS4gVGhlIGJ1bm55IG1pZ2h0IG5lZWQgYmV0dGVyIHBvc2l0aW9uaW5nL21hdGVyaWFsXG4yLiBUaGUgdGVhcG90IG5lZWRzIHRvIGJlIG1vcmUgcHJvbWluZW50IGFzIHRoZSBoZXJvXG4zLiBUaGUgY2hlY2tlcmVkIHNwaGVyZSBuZWVkcyB0byBiZSBtb3JlIHZpc2libGVcbjQuIFRoZSBsaWdodGluZyBtaWdodCBuZWVkIGFkanVzdG1lbnQgZm9yIGJldHRlciBjaGlhcm9zY3Vyb1xuNS4gVGhlIENvcm5lbGwgYm94IHBhbGV0dGUgKHJlZCB2cyBncmVlbikgbmVlZHMgdG8gYmUgc3Ryb25nZXJcblxuTGV0IG1lIGNoZWNrIGlmIHRoZXJlIGFyZSBhbnkgaXNzdWVzIHdpdGggdGhlIG9iamVjdHMnIHBsYWNlbWVudCBhbmQgbWFrZSByZWZpbmVtZW50cy4gTGV0IG1lIGFsc28gbWFrZSBzdXJlIHRoZSBidW5ueSdzIHJlbWVzaCBtb2RpZmllciBpcyB3b3JraW5nIHByb3Blcmx5LlxuXG5MZXQgbWUgZG8gYSBtb3JlIGRldGFpbGVkIGNoZWNrIG9mIHRoZSBvYmplY3RzIGFuZCB0aGVuIHJlZmluZSB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dLCJyZWFzb25pbmdfZGV0YWlscyI6W3sidHlwZSI6InJlYXNvbmluZy50ZXh0IiwidGV4dCI6IkxldCBtZSBhbmFseXplIHRoZSByZW5kZXIgZGF0YSBJIGhhdmUuIFRoZSBpbWFnZSBzaG93czpcbi0gVG9wLWxlZnQ6IGRhcmsgKGJhY2tncm91bmQgd2FsbClcbi0gVG9wLXJpZ2h0OiBncmVlbiAoZ3JlZW4gcGFuZWwpXG4tIENlbnRlcjogYnJpZ2h0IChvYmplY3RzLCB0ZWFwb3QgY2VyYW1pYylcbi0gQm90dG9tLWxlZnQ6IHZlcnkgZGFyayAoc2hhZG93IGFyZWEpXG4tIEJvdHRvbS1yaWdodDogYnJpZ2h0ICh0YWJsZSBlZGdlIGluIGxpZ2h0KVxuXG5UaGUgY29tcG9zaXRpb24gc2VlbXMgdG8gYmUgd29ya2luZy4gTGV0IG1lIG5vdyByZWZpbmUgdGhpbmdzIGJhc2VkIG9uIHdoYXQgSSBjYW4gdGVsbC4gVGhlIGtleSBpc3N1ZXMgSSBuZWVkIHRvIGFkZHJlc3M6XG5cbjEuIFRoZSBidW5ueSBtaWdodCBuZWVkIGJldHRlciBwb3NpdGlvbmluZy9tYXRlcmlhbFxuMi4gVGhlIHRlYXBvdCBuZWVkcyB0byBiZSBtb3JlIHByb21pbmVudCBhcyB0aGUgaGVyb1xuMy4gVGhlIGNoZWNrZXJlZCBzcGhlcmUgbmVlZHMgdG8gYmUgbW9yZSB2aXNpYmxlXG40LiBUaGUgbGlnaHRpbmcgbWlnaHQgbmVlZCBhZGp1c3RtZW50IGZvciBiZXR0ZXIgY2hpYXJvc2N1cm9cbjUuIFRoZSBDb3JuZWxsIGJveCBwYWxldHRlIChyZWQgdnMgZ3JlZW4pIG5lZWRzIHRvIGJlIHN0cm9uZ2VyXG5cbkxldCBtZSBjaGVjayBpZiB0aGVyZSBhcmUgYW55IGlzc3VlcyB3aXRoIHRoZSBvYmplY3RzJyBwbGFjZW1lbnQgYW5kIG1ha2UgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2Ugc3VyZSB0aGUgYnVubnkncyByZW1lc2ggbW9kaWZpZXIgaXMgd29ya2luZyBwcm9wZXJseS5cblxuTGV0IG1lIGRvIGEgbW9yZSBkZXRhaWxlZCBjaGVjayBvZiB0aGUgb2JqZWN0cyBhbmQgdGhlbiByZWZpbmUgdGhlIGNvbXBvc2l0aW9uLiIsImZvcm1hdCI6InVua25vd24iLCJpbmRleCI6MH1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjozMjg0NCwiY29tcGxldGlvbl90b2tlbnMiOjM0MSwidG90YWxfdG9rZW5zIjozMzE4NSwiY29zdCI6MC4wMDY3NzQ2MTUxMiwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjozMjc2OCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDY3NzQ2MTUxMiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNTc3MDg0NzUyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDEwMDM3Njc2fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjoyMjgsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Check all objects and their modifiers\nfor obj in bpy.data.objects:\n    if obj.type == 'MESH':\n        mods = [(m.name, m.type) for m in obj.modifiers]\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\n        print(f\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 32844, "tokens_out": 341, "cost_usd": 0.00677461512, "cached_tokens": 32768}, "error": null}
{"ts": "2026-07-17T15:08:41.295216+00:00", "type": "assistant", "text": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Check all objects and their modifiers\nfor obj in bpy.data.objects:\n    if obj.type == 'MESH':\n        mods = [(m.name, m.type) for m in obj.modifiers]\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\n        print(f\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:08:41.295216+00:00", "type": "tool_call", "id": "chatcmpl-tool-a0fd0dc86e72eae1", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Check all objects and their modifiers\nfor obj in bpy.data.objects:\n    if obj.type == 'MESH':\n        mods = [(m.name, m.type) for m in obj.modifiers]\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\n        print(f\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:08:41.479909+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:08:54.278603+00:00", "type": "llm_call", "call_index": 35, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:08:41.481415+00:00", "finished_at": "2026-07-17T15:08:54.278603+00:00", "duration_s": 12.796000000002095, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:08:41.481415+00:00", "finished_at": "2026-07-17T15:08:54.277602+00:00", "duration_s": 12.796000000002095, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "127974", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:08:45 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300922-lB9ymhuEPNW4XooSNEuE", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca29dadf83dbf5-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300922-lB9ymhuEPNW4XooSNEuE\",\"object\":\"chat.completion\",\"created\":1784300922,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"refusal\":null,\"reasoning\":\"I see several issues:\\n1. RedCloth has duplicate materials (M_RedVelvet and M_RedVelvet.001) - need to clean up\\n2. GreenCloth has material M_GreenVelvet.001 instead of M_GreenVelvet\\n3. The bunny has Remesh modifier which might be causing issues\\n\\nLet me fix these issues and also improve the composition. Let me also clean up duplicate materials.\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"I see several issues:\\n1. RedCloth has duplicate materials (M_RedVelvet and M_RedVelvet.001) - need to clean up\\n2. GreenCloth has material M_GreenVelvet.001 instead of M_GreenVelvet\\n3. The bunny has Remesh modifier which might be causing issues\\n\\nLet me fix these issues and also improve the composition. Let me also clean up duplicate materials.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":34560,\"completion_tokens\":367,\"total_tokens\":34927,\"cost\":0.00840954408,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":32832,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00840954408,\"upstream_inference_prompt_cost\":0.00732924288,\"upstream_inference_completions_cost\":0.0010803012},\"completion_tokens_details\":{\"reasoning_tokens\":88,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMDkyMi1sQjl5bWh1RVBOVzRYb29TTkV1RSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDA5MjIsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSBzb21lIG1hdGVyaWFsIGR1cGxpY2F0aW9uIGlzc3Vlcy4gTGV0IG1lIGNsZWFuIHRob3NlIHVwIGFuZCBtYWtlIHJlZmluZW1lbnRzIHRvIGltcHJvdmUgdGhlIHNjZW5lLiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6Ikkgc2VlIHNldmVyYWwgaXNzdWVzOlxuMS4gUmVkQ2xvdGggaGFzIGR1cGxpY2F0ZSBtYXRlcmlhbHMgKE1fUmVkVmVsdmV0IGFuZCBNX1JlZFZlbHZldC4wMDEpIC0gbmVlZCB0byBjbGVhbiB1cFxuMi4gR3JlZW5DbG90aCBoYXMgbWF0ZXJpYWwgTV9HcmVlblZlbHZldC4wMDEgaW5zdGVhZCBvZiBNX0dyZWVuVmVsdmV0XG4zLiBUaGUgYnVubnkgaGFzIFJlbWVzaCBtb2RpZmllciB3aGljaCBtaWdodCBiZSBjYXVzaW5nIGlzc3Vlc1xuXG5MZXQgbWUgZml4IHRoZXNlIGlzc3VlcyBhbmQgYWxzbyBpbXByb3ZlIHRoZSBjb21wb3NpdGlvbi4gTGV0IG1lIGFsc28gY2xlYW4gdXAgZHVwbGljYXRlIG1hdGVyaWFscy4iLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLTk3NWNmMDkyZWMzZDU5MTkiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbiMgRml4IG1hdGVyaWFsIGFzc2lnbm1lbnRzIC0gY2xlYW4gdXAgZHVwbGljYXRlc1xcbiMgUmVkQ2xvdGggaGFzIGJvdGggTV9SZWRWZWx2ZXQgYW5kIE1fUmVkVmVsdmV0LjAwMVxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl1cXG5yZWRfY2xvdGguZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdKVxcblxcbiMgR3JlZW5DbG90aCBoYXMgTV9HcmVlblZlbHZldC4wMDEgaW5zdGVhZCBvZiBNX0dyZWVuVmVsdmV0XFxuZ3JlZW5fY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlbkNsb3RoXFxcIl1cXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdKVxcblxcbiMgUmVtb3ZlIGR1cGxpY2F0ZSBtYXRlcmlhbHNcXG5mb3IgbWF0X25hbWUgaW4gW1xcXCJNX1JlZFZlbHZldC4wMDFcXFwiLCBcXFwiTV9HcmVlblZlbHZldC4wMDFcXFwiXTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChtYXRfbmFtZSlcXG4gICAgaWYgbWF0OlxcbiAgICAgICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShtYXQpXFxuXFxuIyBWZXJpZnlcXG5mb3IgbmFtZSBpbiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBwcmludChmXFxcIntuYW1lfToge1ttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXX1cXFwiKVxcblxcbnByaW50KGZcXFwiXFxcXG5BbGwgbWF0ZXJpYWxzOiB7W20ubmFtZSBmb3IgbSBpbiBicHkuZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV0sInJlYXNvbmluZ19kZXRhaWxzIjpbeyJ0eXBlIjoicmVhc29uaW5nLnRleHQiLCJ0ZXh0IjoiSSBzZWUgc2V2ZXJhbCBpc3N1ZXM6XG4xLiBSZWRDbG90aCBoYXMgZHVwbGljYXRlIG1hdGVyaWFscyAoTV9SZWRWZWx2ZXQgYW5kIE1fUmVkVmVsdmV0LjAwMSkgLSBuZWVkIHRvIGNsZWFuIHVwXG4yLiBHcmVlbkNsb3RoIGhhcyBtYXRlcmlhbCBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcbjMuIFRoZSBidW5ueSBoYXMgUmVtZXNoIG1vZGlmaWVyIHdoaWNoIG1pZ2h0IGJlIGNhdXNpbmcgaXNzdWVzXG5cbkxldCBtZSBmaXggdGhlc2UgaXNzdWVzIGFuZCBhbHNvIGltcHJvdmUgdGhlIGNvbXBvc2l0aW9uLiBMZXQgbWUgYWxzbyBjbGVhbiB1cCBkdXBsaWNhdGUgbWF0ZXJpYWxzLiIsImZvcm1hdCI6InVua25vd24iLCJpbmRleCI6MH1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjozNDU2MCwiY29tcGxldGlvbl90b2tlbnMiOjM2NywidG90YWxfdG9rZW5zIjozNDkyNywiY29zdCI6MC4wMDg0MDk1NDQwOCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjozMjgzMiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDg0MDk1NDQwOCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNzMyOTI0Mjg4LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDEwODAzMDEyfSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjo4OCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Fix material assignments - clean up duplicates\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\nred_cloth = bpy.data.objects[\"RedCloth\"]\nred_cloth.data.materials.clear()\nred_cloth.data.materials.append(bpy.data.materials[\"M_RedVelvet\"])\n\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\ngreen_cloth = bpy.data.objects[\"GreenCloth\"]\ngreen_cloth.data.materials.clear()\ngreen_cloth.data.materials.append(bpy.data.materials[\"M_GreenVelvet\"])\n\n# Remove duplicate materials\nfor mat_name in [\"M_RedVelvet.001\", \"M_GreenVelvet.001\"]:\n    mat = bpy.data.materials.get(mat_name)\n    if mat:\n        bpy.data.materials.remove(mat)\n\n# Verify\nfor name in [\"RedCloth\", \"GreenCloth\"]:\n    obj = bpy.data.objects[name]\n    print(f\"{name}: {[m.name for m in obj.data.materials]}\")\n\nprint(f\"\\nAll materials: {[m.name for m in bpy.data.materials]}\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 34560, "tokens_out": 367, "cost_usd": 0.00840954408, "cached_tokens": 32832}, "error": null}
{"ts": "2026-07-17T15:08:54.281611+00:00", "type": "assistant", "text": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Fix material assignments - clean up duplicates\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\nred_cloth = bpy.data.objects[\"RedCloth\"]\nred_cloth.data.materials.clear()\nred_cloth.data.materials.append(bpy.data.materials[\"M_RedVelvet\"])\n\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\ngreen_cloth = bpy.data.objects[\"GreenCloth\"]\ngreen_cloth.data.materials.clear()\ngreen_cloth.data.materials.append(bpy.data.materials[\"M_GreenVelvet\"])\n\n# Remove duplicate materials\nfor mat_name in [\"M_RedVelvet.001\", \"M_GreenVelvet.001\"]:\n    mat = bpy.data.materials.get(mat_name)\n    if mat:\n        bpy.data.materials.remove(mat)\n\n# Verify\nfor name in [\"RedCloth\", \"GreenCloth\"]:\n    obj = bpy.data.objects[name]\n    print(f\"{name}: {[m.name for m in obj.data.materials]}\")\n\nprint(f\"\\nAll materials: {[m.name for m in bpy.data.materials]}\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:08:54.281611+00:00", "type": "tool_call", "id": "chatcmpl-tool-975cf092ec3d5919", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Fix material assignments - clean up duplicates\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\nred_cloth = bpy.data.objects[\"RedCloth\"]\nred_cloth.data.materials.clear()\nred_cloth.data.materials.append(bpy.data.materials[\"M_RedVelvet\"])\n\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\ngreen_cloth = bpy.data.objects[\"GreenCloth\"]\ngreen_cloth.data.materials.clear()\ngreen_cloth.data.materials.append(bpy.data.materials[\"M_GreenVelvet\"])\n\n# Remove duplicate materials\nfor mat_name in [\"M_RedVelvet.001\", \"M_GreenVelvet.001\"]:\n    mat = bpy.data.materials.get(mat_name)\n    if mat:\n        bpy.data.materials.remove(mat)\n\n# Verify\nfor name in [\"RedCloth\", \"GreenCloth\"]:\n    obj = bpy.data.objects[name]\n    print(f\"{name}: {[m.name for m in obj.data.materials]}\")\n\nprint(f\"\\nAll materials: {[m.name for m in bpy.data.materials]}\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:08:54.681027+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:09:20.710404+00:00", "type": "llm_call", "call_index": 36, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:08:54.682035+00:00", "finished_at": "2026-07-17T15:09:20.710404+00:00", "duration_s": 26.014999999984866, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:08:54.682035+00:00", "finished_at": "2026-07-17T15:09:20.709895+00:00", "duration_s": 26.014999999984866, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "129801", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:09:08 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300946-b9G0PYVkkKyE4d7zPrKl", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2a749d1e03d9-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300946-b9G0PYVkkKyE4d7zPrKl\",\"object\":\"chat.completion\",\"created\":1784300946,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":35013,\"completion_tokens\":488,\"total_tokens\":35501,\"cost\":0.007872123,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":34560,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.007872123,\"upstream_inference_prompt_cost\":0.0064356462,\"upstream_inference_completions_cost\":0.0014364768},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA5NDYtYjlHMFBZVmtrS3lFNGQ3elByS2wiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwOTQ2LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjozNTAxMywiY29tcGxldGlvbl90b2tlbnMiOjQ4OCwidG90YWxfdG9rZW5zIjozNTUwMSwiY29zdCI6MC4wMDc4NzIxMjMsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MzQ1NjAsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA3ODcyMTIzLCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA2NDM1NjQ2MiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAxNDM2NDc2OH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\n# Fix Suzanne base positioning\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\n# The base should be under her, on the table\n\nsuzanne = bpy.data.objects[\"Suzanne\"]\nbase = bpy.data.objects[\"SuzanneBase\"]\n\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\n# Place base right under her\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\nbase.scale = (1.0, 1.0, 1.0)\n\n# Make sure Suzanne is resting on the base\nsuzanne.location.z = 0.18\n\n# Apply Suzanne's rotation to the base too\nbase.rotation_euler = (0, 0, 0)\n\nprint(f\"Suzanne: {list(suzanne.location)}\")\nprint(f\"Base: {list(base.location)}\")\n\n# Now let me also check the bunny - make sure it sits on the table\nbunny = bpy.data.objects[\"StanfordBunny\"]\n# The bunny's lowest point should be at z=0 (table surface)\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\n# Let's check its bounding box\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\n# Lowest parts are the paws at z=0, so it should sit on table\nbunny.location.z = 0.03  # slight lift for cloth thickness\n\n# Adjust bunny rotation so it faces slightly toward camera\nbunny.rotation_euler = (0, 0, math.radians(40))\n\nprint(f\"Bunny: {list(bunny.location)}\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 35013, "tokens_out": 488, "cost_usd": 0.007872123, "cached_tokens": 34560}, "error": null}
{"ts": "2026-07-17T15:09:20.713442+00:00", "type": "assistant", "text": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\n# Fix Suzanne base positioning\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\n# The base should be under her, on the table\n\nsuzanne = bpy.data.objects[\"Suzanne\"]\nbase = bpy.data.objects[\"SuzanneBase\"]\n\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\n# Place base right under her\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\nbase.scale = (1.0, 1.0, 1.0)\n\n# Make sure Suzanne is resting on the base\nsuzanne.location.z = 0.18\n\n# Apply Suzanne's rotation to the base too\nbase.rotation_euler = (0, 0, 0)\n\nprint(f\"Suzanne: {list(suzanne.location)}\")\nprint(f\"Base: {list(base.location)}\")\n\n# Now let me also check the bunny - make sure it sits on the table\nbunny = bpy.data.objects[\"StanfordBunny\"]\n# The bunny's lowest point should be at z=0 (table surface)\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\n# Let's check its bounding box\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\n# Lowest parts are the paws at z=0, so it should sit on table\nbunny.location.z = 0.03  # slight lift for cloth thickness\n\n# Adjust bunny rotation so it faces slightly toward camera\nbunny.rotation_euler = (0, 0, math.radians(40))\n\nprint(f\"Bunny: {list(bunny.location)}\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:09:20.713442+00:00", "type": "tool_call", "id": "chatcmpl-tool-a250101a80c6b1b3", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\n# Fix Suzanne base positioning\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\n# The base should be under her, on the table\n\nsuzanne = bpy.data.objects[\"Suzanne\"]\nbase = bpy.data.objects[\"SuzanneBase\"]\n\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\n# Place base right under her\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\nbase.scale = (1.0, 1.0, 1.0)\n\n# Make sure Suzanne is resting on the base\nsuzanne.location.z = 0.18\n\n# Apply Suzanne's rotation to the base too\nbase.rotation_euler = (0, 0, 0)\n\nprint(f\"Suzanne: {list(suzanne.location)}\")\nprint(f\"Base: {list(base.location)}\")\n\n# Now let me also check the bunny - make sure it sits on the table\nbunny = bpy.data.objects[\"StanfordBunny\"]\n# The bunny's lowest point should be at z=0 (table surface)\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\n# Let's check its bounding box\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\n# Lowest parts are the paws at z=0, so it should sit on table\nbunny.location.z = 0.03  # slight lift for cloth thickness\n\n# Adjust bunny rotation so it faces slightly toward camera\nbunny.rotation_euler = (0, 0, math.radians(40))\n\nprint(f\"Bunny: {list(bunny.location)}\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:09:21.284359+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:09:27.564842+00:00", "type": "llm_call", "call_index": 37, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:09:21.286040+00:00", "finished_at": "2026-07-17T15:09:27.564842+00:00", "duration_s": 6.282000000006519, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:09:21.286040+00:00", "finished_at": "2026-07-17T15:09:27.564842+00:00", "duration_s": 6.282000000006519, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "131978", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:09:24 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300962-q2rb34y59nCmkLFI5mTc", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2ad4aa0c4f18-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300962-q2rb34y59nCmkLFI5mTc\",\"object\":\"chat.completion\",\"created\":1784300962,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-b61f025e64068731\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":35636,\"completion_tokens\":120,\"total_tokens\":35756,\"cost\":0.00703070832,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":35008,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00703070832,\"upstream_inference_prompt_cost\":0.00667747632,\"upstream_inference_completions_cost\":0.000353232},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDA5NjItcTJyYjM0eTU5bkNta0xGSTVtVGMiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAwOTYyLCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIEknbGwgcmVkdWNlIHNhbXBsZXMgdGVtcG9yYXJpbHkgZm9yIGZhc3RlciBmZWVkYmFjay4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBUZW1wb3JhcmlseSByZWR1Y2Ugc2FtcGxlcyBmb3IgZmFzdGVyIHByZXZpZXdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcblxcbiMgU2V0IHJlbmRlciBvdXRwdXRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzIucG5nXFxcIlxcblxcbiMgUmVuZGVyXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxucHJpbnQoXFxcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjM1NjM2LCJjb21wbGV0aW9uX3Rva2VucyI6MTIwLCJ0b3RhbF90b2tlbnMiOjM1NzU2LCJjb3N0IjowLjAwNzAzMDcwODMyLCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjM1MDA4LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwNzAzMDcwODMyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA2Njc3NDc2MzIsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMDM1MzIzMn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Temporarily reduce samples for faster preview\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.cycles.use_denoising = True\n\n# Set render output\nscene.render.filepath = \"C:/tmp/still_life_preview2.png\"\n\n# Render\nbpy.ops.render.render(write_still=True)\n\nprint(\"Preview render complete.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 35636, "tokens_out": 120, "cost_usd": 0.00703070832, "cached_tokens": 35008}, "error": null}
{"ts": "2026-07-17T15:09:27.568356+00:00", "type": "assistant", "text": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Temporarily reduce samples for faster preview\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.cycles.use_denoising = True\n\n# Set render output\nscene.render.filepath = \"C:/tmp/still_life_preview2.png\"\n\n# Render\nbpy.ops.render.render(write_still=True)\n\nprint(\"Preview render complete.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:09:27.568356+00:00", "type": "tool_call", "id": "chatcmpl-tool-b61f025e64068731", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Temporarily reduce samples for faster preview\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.cycles.use_denoising = True\n\n# Set render output\nscene.render.filepath = \"C:/tmp/still_life_preview2.png\"\n\n# Render\nbpy.ops.render.render(write_still=True)\n\nprint(\"Preview render complete.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:09:54.354545+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:10:06.079157+00:00", "type": "llm_call", "call_index": 38, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:09:54.355553+00:00", "finished_at": "2026-07-17T15:10:06.079157+00:00", "duration_s": 11.71799999999348, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:09:54.355553+00:00", "finished_at": "2026-07-17T15:10:06.077652+00:00", "duration_s": 11.71799999999348, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "132865", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:09:56 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784300995-wDpQgaQxnqmTpbzvNlKf", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2ba2acadecae-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784300995-wDpQgaQxnqmTpbzvNlKf\",\"object\":\"chat.completion\",\"created\":1784300995,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-838028367162311c\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":35794,\"completion_tokens\":404,\"total_tokens\":36198,\"cost\":0.00757538136,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":35584,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00757538136,\"upstream_inference_prompt_cost\":0.00638616696,\"upstream_inference_completions_cost\":0.0011892144},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAwOTk1LXdEcFFnYVF4bnFtVHBienZObEtmIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMDk5NSwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MzU3OTQsImNvbXBsZXRpb25fdG9rZW5zIjo0MDQsInRvdGFsX3Rva2VucyI6MzYxOTgsImNvc3QiOjAuMDA3NTc1MzgxMzYsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MzU1ODQsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA3NTc1MzgxMzYsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDYzODYxNjY5NiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAxMTg5MjE0NH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview2.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Detailed grid analysis\nprint(f\"Image: {w}x{h}\")\nprint(\"\\nBrightness map (4x6 grid):\")\nfor gy in range(6):\n    row = \"\"\n    for gx in range(6):\n        x1 = gx * w // 6\n        x2 = (gx+1) * w // 6\n        y1 = gy * h // 6\n        y2 = (gy+1) * h // 6\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 15):\n            for x in range(x1, x2, 15):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        # Create ASCII brightness map\n        if bright < 0.1: row += \"  \"\n        elif bright < 0.2: row += \"· \"\n        elif bright < 0.3: row += \"• \"\n        elif bright < 0.4: row += \"○ \"\n        elif bright < 0.5: row += \"☀ \"\n        elif bright < 0.6: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 35794, "tokens_out": 404, "cost_usd": 0.00757538136, "cached_tokens": 35584}, "error": null}
{"ts": "2026-07-17T15:10:06.082665+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview2.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Detailed grid analysis\nprint(f\"Image: {w}x{h}\")\nprint(\"\\nBrightness map (4x6 grid):\")\nfor gy in range(6):\n    row = \"\"\n    for gx in range(6):\n        x1 = gx * w // 6\n        x2 = (gx+1) * w // 6\n        y1 = gy * h // 6\n        y2 = (gy+1) * h // 6\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 15):\n            for x in range(x1, x2, 15):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        # Create ASCII brightness map\n        if bright < 0.1: row += \"  \"\n        elif bright < 0.2: row += \"· \"\n        elif bright < 0.3: row += \"• \"\n        elif bright < 0.4: row += \"○ \"\n        elif bright < 0.5: row += \"☀ \"\n        elif bright < 0.6: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:10:06.082665+00:00", "type": "tool_call", "id": "chatcmpl-tool-838028367162311c", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview2.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Detailed grid analysis\nprint(f\"Image: {w}x{h}\")\nprint(\"\\nBrightness map (4x6 grid):\")\nfor gy in range(6):\n    row = \"\"\n    for gx in range(6):\n        x1 = gx * w // 6\n        x2 = (gx+1) * w // 6\n        y1 = gy * h // 6\n        y2 = (gy+1) * h // 6\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 15):\n            for x in range(x1, x2, 15):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        # Create ASCII brightness map\n        if bright < 0.1: row += \"  \"\n        elif bright < 0.2: row += \"· \"\n        elif bright < 0.3: row += \"• \"\n        elif bright < 0.4: row += \"○ \"\n        elif bright < 0.5: row += \"☀ \"\n        elif bright < 0.6: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:10:06.788560+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-838028367162311c", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:10:13.593820+00:00", "type": "llm_call", "call_index": 39, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:10:06.789564+00:00", "finished_at": "2026-07-17T15:10:13.592809+00:00", "duration_s": 6.812999999994645, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:10:06.789564+00:00", "finished_at": "2026-07-17T15:10:13.591300+00:00", "duration_s": 6.812999999994645, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "134817", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:10:09 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301007-MmaLLa8cRJcIMaibBUsd", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2bf009199825-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301007-MmaLLa8cRJcIMaibBUsd\",\"object\":\"chat.completion\",\"created\":1784301007,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":36353,\"completion_tokens\":152,\"total_tokens\":36505,\"cost\":0.00721072284,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":35776,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00721072284,\"upstream_inference_prompt_cost\":0.00676329564,\"upstream_inference_completions_cost\":0.0004474272},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxMDA3LU1tYUxMYThjUkpjSU1haWJCVXNkIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTAwNywibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkkgY2FuIHNlZSB0aGUgY29tcG9zaXRpb24gaXMgdGFraW5nIHNoYXBlIC0gYnJpZ2h0IG9iamVjdHMgaW4gdGhlIGNlbnRlciBhbmQgbG93ZXItbGVmdCwgd2l0aCB0aGUgdGFibGUgZWRnZSB2aXNpYmxlIGF0IHRoZSBib3R0b20uIExldCBtZSB2aWV3IHRoZSBhY3R1YWwgc2NyZWVuc2hvdCBub3cuIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLTg4OTBjMDA3ZmNjZTg1ZWIiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbiMgU2V0IHRoZSByZW5kZXIgb3V0cHV0IHRvIHNob3cgaW4gdGhlIGltYWdlIGVkaXRvclxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdJTUFHRV9FRElUT1InOlxcbiAgICAgICAgZm9yIHNwYWNlIGluIGFyZWEuc3BhY2VzOlxcbiAgICAgICAgICAgIGlmIHNwYWNlLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICAgICAgICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbiAgICAgICAgICAgICAgICBzcGFjZS5pbWFnZSA9IGltZ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5cXG4jIEFsc28gdHJ5IHRvIHZpZXcgaXQgaW4gdGhlIDNEIHZpZXdwb3J0IGFzIGJhY2tncm91bmRcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MzYzNTMsImNvbXBsZXRpb25fdG9rZW5zIjoxNTIsInRvdGFsX3Rva2VucyI6MzY1MDUsImNvc3QiOjAuMDA3MjEwNzIyODQsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MzU3NzYsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA3MjEwNzIyODQsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDY3NjMyOTU2NCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAwNDQ3NDI3Mn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Set the render output to show in the image editor\nfor area in bpy.context.screen.areas:\n    if area.type == 'IMAGE_EDITOR':\n        for space in area.spaces:\n            if space.type == 'IMAGE_EDITOR':\n                img = bpy.data.images.load(\"C:/tmp/still_life_preview2.png\")\n                space.image = img\n                break\n        break\n\n# Also try to view it in the 3D viewport as background\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 36353, "tokens_out": 152, "cost_usd": 0.00721072284, "cached_tokens": 35776}, "error": null}
{"ts": "2026-07-17T15:10:13.597336+00:00", "type": "assistant", "text": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Set the render output to show in the image editor\nfor area in bpy.context.screen.areas:\n    if area.type == 'IMAGE_EDITOR':\n        for space in area.spaces:\n            if space.type == 'IMAGE_EDITOR':\n                img = bpy.data.images.load(\"C:/tmp/still_life_preview2.png\")\n                space.image = img\n                break\n        break\n\n# Also try to view it in the 3D viewport as background\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:10:13.597336+00:00", "type": "tool_call", "id": "chatcmpl-tool-8890c007fcce85eb", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Set the render output to show in the image editor\nfor area in bpy.context.screen.areas:\n    if area.type == 'IMAGE_EDITOR':\n        for space in area.spaces:\n            if space.type == 'IMAGE_EDITOR':\n                img = bpy.data.images.load(\"C:/tmp/still_life_preview2.png\")\n                space.image = img\n                break\n        break\n\n# Also try to view it in the 3D viewport as background\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:10:13.926856+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:10:17.123997+00:00", "type": "llm_call", "call_index": 40, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:10:13.927856+00:00", "finished_at": "2026-07-17T15:10:17.122996+00:00", "duration_s": 3.2030000000086147, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:10:13.927856+00:00", "finished_at": "2026-07-17T15:10:17.122488+00:00", "duration_s": 3.2030000000086147, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "135813", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:10:17 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301014-9C88QBWwSCJr7mQAtq0t", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2c1ca86ecf94-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301014-9C88QBWwSCJr7mQAtq0t\",\"object\":\"chat.completion\",\"created\":1784301014,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":36532,\"completion_tokens\":22,\"total_tokens\":36554,\"cost\":0.00655641408,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":36352,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00655641408,\"upstream_inference_prompt_cost\":0.00649165488,\"upstream_inference_completions_cost\":0.0000647592},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxMDE0LTlDODhRQld3U0NKcjdtUUF0cTB0Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTAxNCwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjozNjUzMiwiY29tcGxldGlvbl90b2tlbnMiOjIyLCJ0b3RhbF90b2tlbnMiOjM2NTU0LCJjb3N0IjowLjAwNjU1NjQxNDA4LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjM2MzUyLCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwNjU1NjQxNDA4LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA2NDkxNjU0ODgsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMDA2NDc1OTJ9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}], "tokens_in": 36532, "tokens_out": 22, "cost_usd": 0.00655641408, "cached_tokens": 36352}, "error": null}
{"ts": "2026-07-17T15:10:17.126998+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:10:17.126998+00:00", "type": "tool_call", "id": "chatcmpl-tool-a31aecfdef27c07a", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}
{"ts": "2026-07-17T15:10:17.574765+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "name": "get_screenshot_of_area_as_image", "text": "", "is_error": false, "has_image": true, "image_b64": "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"}
{"ts": "2026-07-17T15:10:48.035586+00:00", "type": "llm_call", "call_index": 41, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:10:17.578332+00:00", "finished_at": "2026-07-17T15:10:48.035586+00:00", "duration_s": 30.453000000008615, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:10:17.578332+00:00", "finished_at": "2026-07-17T15:10:48.034586+00:00", "duration_s": 30.453000000008615, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "136099", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:10:20 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301018-KixgXiXpoKkZicPi9Pyw", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2c336cc40366-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301018-KixgXiXpoKkZicPi9Pyw\",\"object\":\"chat.completion\",\"created\":1784301018,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"refusal\":null,\"reasoning\":\"Let me analyze what I've built so far and think about what improvements to make. From the brightness map, I can see:\\n- The composition has objects in the center and lower portions\\n- The lighting is creating good chiaroscuro with darker areas on the left and right edges\\n- The table edge is visible at the bottom\\n\\nHowever, I need to make several refinements:\\n1. The composition needs to be more carefully arranged - the teapot should \\\"command\\\" the arrangement\\n2. The lighting could be more dramatic - stronger chiaroscuro\\n3. The Cornell box palette (red vs green) needs to be more prominent\\n4. The teapot material needs to be more Vermeer-worthy - perhaps silver\\n5. The drapery needs better fold structure\\n6. The bunny needs to look more recognizable\\n\\nLet me make these refinements. First, let me look at the actual rendered image more carefully by examining the pixel data in specific regions where I expect each object to be.\\n\\nActually, let me just proceed with improvements based on what I know about the scene. The key issues I want to address:\\n1. Make the teapot more prominent and give it a better material\\n2. Improve the lighting to be more dramatic chiaroscuro\\n3. Make the Cornell palette more obvious\\n4. Improve the drapery\\n5. Add a window frame element to sell the \\\"shaft of light\\\" concept\\n\\nLet me also consider the camera angle - it should be slightly elevated, intimate, 50mm. The current camera at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4) seems reasonable but let me refine it.\\n\\nLet me make several key improvements now.\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"Let me analyze what I've built so far and think about what improvements to make. From the brightness map, I can see:\\n- The composition has objects in the center and lower portions\\n- The lighting is creating good chiaroscuro with darker areas on the left and right edges\\n- The table edge is visible at the bottom\\n\\nHowever, I need to make several refinements:\\n1. The composition needs to be more carefully arranged - the teapot should \\\"command\\\" the arrangement\\n2. The lighting could be more dramatic - stronger chiaroscuro\\n3. The Cornell box palette (red vs green) needs to be more prominent\\n4. The teapot material needs to be more Vermeer-worthy - perhaps silver\\n5. The drapery needs better fold structure\\n6. The bunny needs to look more recognizable\\n\\nLet me make these refinements. First, let me look at the actual rendered image more carefully by examining the pixel data in specific regions where I expect each object to be.\\n\\nActually, let me just proceed with improvements based on what I know about the scene. The key issues I want to address:\\n1. Make the teapot more prominent and give it a better material\\n2. Improve the lighting to be more dramatic chiaroscuro\\n3. Make the Cornell palette more obvious\\n4. Improve the drapery\\n5. Add a window frame element to sell the \\\"shaft of light\\\" concept\\n\\nLet me also consider the camera angle - it should be slightly elevated, intimate, 50mm. The current camera at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4) seems reasonable but let me refine it.\\n\\nLet me make several key improvements now.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":36558,\"completion_tokens\":1118,\"total_tokens\":37676,\"cost\":0.0097093308,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":36480,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0097093308,\"upstream_inference_prompt_cost\":0.006418386,\"upstream_inference_completions_cost\":0.0032909448},\"completion_tokens_details\":{\"reasoning_tokens\":390,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTAxOC1LaXhnWGlYcG9La1ppY1BpOVB5dyIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDEwMTgsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgbWFrZSBzaWduaWZpY2FudCBpbXByb3ZlbWVudHMgdG8gdGhlIHNjZW5lLiBJJ2xsIHJlZmluZSB0aGUgbGlnaHRpbmcgZm9yIGJldHRlciBjaGlhcm9zY3VybywgaW1wcm92ZSB0aGUgdGVhcG90IG1hdGVyaWFsLCBhbmQgYWRqdXN0IHRoZSBjb21wb3NpdGlvbi4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOiJMZXQgbWUgYW5hbHl6ZSB3aGF0IEkndmUgYnVpbHQgc28gZmFyIGFuZCB0aGluayBhYm91dCB3aGF0IGltcHJvdmVtZW50cyB0byBtYWtlLiBGcm9tIHRoZSBicmlnaHRuZXNzIG1hcCwgSSBjYW4gc2VlOlxuLSBUaGUgY29tcG9zaXRpb24gaGFzIG9iamVjdHMgaW4gdGhlIGNlbnRlciBhbmQgbG93ZXIgcG9ydGlvbnNcbi0gVGhlIGxpZ2h0aW5nIGlzIGNyZWF0aW5nIGdvb2QgY2hpYXJvc2N1cm8gd2l0aCBkYXJrZXIgYXJlYXMgb24gdGhlIGxlZnQgYW5kIHJpZ2h0IGVkZ2VzXG4tIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbVxuXG5Ib3dldmVyLCBJIG5lZWQgdG8gbWFrZSBzZXZlcmFsIHJlZmluZW1lbnRzOlxuMS4gVGhlIGNvbXBvc2l0aW9uIG5lZWRzIHRvIGJlIG1vcmUgY2FyZWZ1bGx5IGFycmFuZ2VkIC0gdGhlIHRlYXBvdCBzaG91bGQgXCJjb21tYW5kXCIgdGhlIGFycmFuZ2VtZW50XG4yLiBUaGUgbGlnaHRpbmcgY291bGQgYmUgbW9yZSBkcmFtYXRpYyAtIHN0cm9uZ2VyIGNoaWFyb3NjdXJvXG4zLiBUaGUgQ29ybmVsbCBib3ggcGFsZXR0ZSAocmVkIHZzIGdyZWVuKSBuZWVkcyB0byBiZSBtb3JlIHByb21pbmVudFxuNC4gVGhlIHRlYXBvdCBtYXRlcmlhbCBuZWVkcyB0byBiZSBtb3JlIFZlcm1lZXItd29ydGh5IC0gcGVyaGFwcyBzaWx2ZXJcbjUuIFRoZSBkcmFwZXJ5IG5lZWRzIGJldHRlciBmb2xkIHN0cnVjdHVyZVxuNi4gVGhlIGJ1bm55IG5lZWRzIHRvIGxvb2sgbW9yZSByZWNvZ25pemFibGVcblxuTGV0IG1lIG1ha2UgdGhlc2UgcmVmaW5lbWVudHMuIEZpcnN0LCBsZXQgbWUgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IGV4YW1pbmluZyB0aGUgcGl4ZWwgZGF0YSBpbiBzcGVjaWZpYyByZWdpb25zIHdoZXJlIEkgZXhwZWN0IGVhY2ggb2JqZWN0IHRvIGJlLlxuXG5BY3R1YWxseSwgbGV0IG1lIGp1c3QgcHJvY2VlZCB3aXRoIGltcHJvdmVtZW50cyBiYXNlZCBvbiB3aGF0IEkga25vdyBhYm91dCB0aGUgc2NlbmUuIFRoZSBrZXkgaXNzdWVzIEkgd2FudCB0byBhZGRyZXNzOlxuMS4gTWFrZSB0aGUgdGVhcG90IG1vcmUgcHJvbWluZW50IGFuZCBnaXZlIGl0IGEgYmV0dGVyIG1hdGVyaWFsXG4yLiBJbXByb3ZlIHRoZSBsaWdodGluZyB0byBiZSBtb3JlIGRyYW1hdGljIGNoaWFyb3NjdXJvXG4zLiBNYWtlIHRoZSBDb3JuZWxsIHBhbGV0dGUgbW9yZSBvYnZpb3VzXG40LiBJbXByb3ZlIHRoZSBkcmFwZXJ5XG41LiBBZGQgYSB3aW5kb3cgZnJhbWUgZWxlbWVudCB0byBzZWxsIHRoZSBcInNoYWZ0IG9mIGxpZ2h0XCIgY29uY2VwdFxuXG5MZXQgbWUgYWxzbyBjb25zaWRlciB0aGUgY2FtZXJhIGFuZ2xlIC0gaXQgc2hvdWxkIGJlIHNsaWdodGx5IGVsZXZhdGVkLCBpbnRpbWF0ZSwgNTBtbS4gVGhlIGN1cnJlbnQgY2FtZXJhIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpIHNlZW1zIHJlYXNvbmFibGUgYnV0IGxldCBtZSByZWZpbmUgaXQuXG5cbkxldCBtZSBtYWtlIHNldmVyYWwga2V5IGltcHJvdmVtZW50cyBub3cuIiwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XSwicmVhc29uaW5nX2RldGFpbHMiOlt7InR5cGUiOiJyZWFzb25pbmcudGV4dCIsInRleHQiOiJMZXQgbWUgYW5hbHl6ZSB3aGF0IEkndmUgYnVpbHQgc28gZmFyIGFuZCB0aGluayBhYm91dCB3aGF0IGltcHJvdmVtZW50cyB0byBtYWtlLiBGcm9tIHRoZSBicmlnaHRuZXNzIG1hcCwgSSBjYW4gc2VlOlxuLSBUaGUgY29tcG9zaXRpb24gaGFzIG9iamVjdHMgaW4gdGhlIGNlbnRlciBhbmQgbG93ZXIgcG9ydGlvbnNcbi0gVGhlIGxpZ2h0aW5nIGlzIGNyZWF0aW5nIGdvb2QgY2hpYXJvc2N1cm8gd2l0aCBkYXJrZXIgYXJlYXMgb24gdGhlIGxlZnQgYW5kIHJpZ2h0IGVkZ2VzXG4tIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbVxuXG5Ib3dldmVyLCBJIG5lZWQgdG8gbWFrZSBzZXZlcmFsIHJlZmluZW1lbnRzOlxuMS4gVGhlIGNvbXBvc2l0aW9uIG5lZWRzIHRvIGJlIG1vcmUgY2FyZWZ1bGx5IGFycmFuZ2VkIC0gdGhlIHRlYXBvdCBzaG91bGQgXCJjb21tYW5kXCIgdGhlIGFycmFuZ2VtZW50XG4yLiBUaGUgbGlnaHRpbmcgY291bGQgYmUgbW9yZSBkcmFtYXRpYyAtIHN0cm9uZ2VyIGNoaWFyb3NjdXJvXG4zLiBUaGUgQ29ybmVsbCBib3ggcGFsZXR0ZSAocmVkIHZzIGdyZWVuKSBuZWVkcyB0byBiZSBtb3JlIHByb21pbmVudFxuNC4gVGhlIHRlYXBvdCBtYXRlcmlhbCBuZWVkcyB0byBiZSBtb3JlIFZlcm1lZXItd29ydGh5IC0gcGVyaGFwcyBzaWx2ZXJcbjUuIFRoZSBkcmFwZXJ5IG5lZWRzIGJldHRlciBmb2xkIHN0cnVjdHVyZVxuNi4gVGhlIGJ1bm55IG5lZWRzIHRvIGxvb2sgbW9yZSByZWNvZ25pemFibGVcblxuTGV0IG1lIG1ha2UgdGhlc2UgcmVmaW5lbWVudHMuIEZpcnN0LCBsZXQgbWUgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IGV4YW1pbmluZyB0aGUgcGl4ZWwgZGF0YSBpbiBzcGVjaWZpYyByZWdpb25zIHdoZXJlIEkgZXhwZWN0IGVhY2ggb2JqZWN0IHRvIGJlLlxuXG5BY3R1YWxseSwgbGV0IG1lIGp1c3QgcHJvY2VlZCB3aXRoIGltcHJvdmVtZW50cyBiYXNlZCBvbiB3aGF0IEkga25vdyBhYm91dCB0aGUgc2NlbmUuIFRoZSBrZXkgaXNzdWVzIEkgd2FudCB0byBhZGRyZXNzOlxuMS4gTWFrZSB0aGUgdGVhcG90IG1vcmUgcHJvbWluZW50IGFuZCBnaXZlIGl0IGEgYmV0dGVyIG1hdGVyaWFsXG4yLiBJbXByb3ZlIHRoZSBsaWdodGluZyB0byBiZSBtb3JlIGRyYW1hdGljIGNoaWFyb3NjdXJvXG4zLiBNYWtlIHRoZSBDb3JuZWxsIHBhbGV0dGUgbW9yZSBvYnZpb3VzXG40LiBJbXByb3ZlIHRoZSBkcmFwZXJ5XG41LiBBZGQgYSB3aW5kb3cgZnJhbWUgZWxlbWVudCB0byBzZWxsIHRoZSBcInNoYWZ0IG9mIGxpZ2h0XCIgY29uY2VwdFxuXG5MZXQgbWUgYWxzbyBjb25zaWRlciB0aGUgY2FtZXJhIGFuZ2xlIC0gaXQgc2hvdWxkIGJlIHNsaWdodGx5IGVsZXZhdGVkLCBpbnRpbWF0ZSwgNTBtbS4gVGhlIGN1cnJlbnQgY2FtZXJhIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpIHNlZW1zIHJlYXNvbmFibGUgYnV0IGxldCBtZSByZWZpbmUgaXQuXG5cbkxldCBtZSBtYWtlIHNldmVyYWwga2V5IGltcHJvdmVtZW50cyBub3cuIiwiZm9ybWF0IjoidW5rbm93biIsImluZGV4IjowfV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjM2NTU4LCJjb21wbGV0aW9uX3Rva2VucyI6MTExOCwidG90YWxfdG9rZW5zIjozNzY3NiwiY29zdCI6MC4wMDk3MDkzMzA4LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjM2NDgwLCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwOTcwOTMzMDgsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDY0MTgzODYsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMzI5MDk0NDh9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjM5MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# REFINEMENTS: Better lighting, composition, and materials\n# ============================================================\n\n# --- 1. Improve lighting for stronger chiaroscuro ---\n# Remove existing lights\nfor obj in list(bpy.data.objects):\n    if obj.type == 'LIGHT':\n        bpy.data.objects.remove(obj, do_unlink=True)\n\n# Key light: warm window shaft from upper-left, more dramatic\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\nkey_light = bpy.context.active_object\nkey_light.name = \"KeyLight_WarmShaft\"\nkey_light.data.energy = 1200\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\nkey_light.data.size = 1.5\nkey_light.data.size_y = 2.5\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\n\n# Very subtle fill from right to prevent total blackness\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\nfill_light = bpy.context.active_object\nfill_light.name = \"FillLight_Dim\"\nfill_light.data.energy = 15\nfill_light.data.color = (0.5, 0.6, 0.8)\nfill_light.data.size = 4.0\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\n\n# Subtle warm rim from behind-right to separate objects\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\nrim_light = bpy.context.active_object\nrim_light.name = \"RimLight_Warm\"\nrim_light.data.energy = 40\nrim_light.data.color = (1.0, 0.75, 0.4)\nrim_light.data.size = 2.0\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\n\n# --- 2. Add a window frame to create light shaft pattern ---\n# Window frame (dark wood, partially visible on left)\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\nwindow_frame = bpy.context.active_object\nwindow_frame.name = \"WindowFrame\"\nwindow_frame.scale = (0.1, 2.0, 3.0)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Assign dark wood material\nwindow_frame.data.materials.append(bpy.data.materials[\"M_TableTop\"])\n\n# --- 3. Adjust camera for better composition ---\ncam = bpy.data.objects[\"Camera_Presentation\"]\ncam.location = (3.5, -4.0, 2.0)\ntarget = Vector((-0.1, 0.0, 0.35))\ndirection = target - cam.location\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\ncam.data.dof.focus_distance = (cam.location - target).length\n\nprint(\"Lighting and camera refined.\")\nresult = {\"lights\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}", "parse_error": null}], "tokens_in": 36558, "tokens_out": 1118, "cost_usd": 0.0097093308, "cached_tokens": 36480}, "error": null}
{"ts": "2026-07-17T15:10:48.039084+00:00", "type": "assistant", "text": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# REFINEMENTS: Better lighting, composition, and materials\n# ============================================================\n\n# --- 1. Improve lighting for stronger chiaroscuro ---\n# Remove existing lights\nfor obj in list(bpy.data.objects):\n    if obj.type == 'LIGHT':\n        bpy.data.objects.remove(obj, do_unlink=True)\n\n# Key light: warm window shaft from upper-left, more dramatic\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\nkey_light = bpy.context.active_object\nkey_light.name = \"KeyLight_WarmShaft\"\nkey_light.data.energy = 1200\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\nkey_light.data.size = 1.5\nkey_light.data.size_y = 2.5\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\n\n# Very subtle fill from right to prevent total blackness\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\nfill_light = bpy.context.active_object\nfill_light.name = \"FillLight_Dim\"\nfill_light.data.energy = 15\nfill_light.data.color = (0.5, 0.6, 0.8)\nfill_light.data.size = 4.0\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\n\n# Subtle warm rim from behind-right to separate objects\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\nrim_light = bpy.context.active_object\nrim_light.name = \"RimLight_Warm\"\nrim_light.data.energy = 40\nrim_light.data.color = (1.0, 0.75, 0.4)\nrim_light.data.size = 2.0\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\n\n# --- 2. Add a window frame to create light shaft pattern ---\n# Window frame (dark wood, partially visible on left)\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\nwindow_frame = bpy.context.active_object\nwindow_frame.name = \"WindowFrame\"\nwindow_frame.scale = (0.1, 2.0, 3.0)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Assign dark wood material\nwindow_frame.data.materials.append(bpy.data.materials[\"M_TableTop\"])\n\n# --- 3. Adjust camera for better composition ---\ncam = bpy.data.objects[\"Camera_Presentation\"]\ncam.location = (3.5, -4.0, 2.0)\ntarget = Vector((-0.1, 0.0, 0.35))\ndirection = target - cam.location\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\ncam.data.dof.focus_distance = (cam.location - target).length\n\nprint(\"Lighting and camera refined.\")\nresult = {\"lights\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:10:48.039084+00:00", "type": "tool_call", "id": "chatcmpl-tool-a6b2fe3e89402cda", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# REFINEMENTS: Better lighting, composition, and materials\n# ============================================================\n\n# --- 1. Improve lighting for stronger chiaroscuro ---\n# Remove existing lights\nfor obj in list(bpy.data.objects):\n    if obj.type == 'LIGHT':\n        bpy.data.objects.remove(obj, do_unlink=True)\n\n# Key light: warm window shaft from upper-left, more dramatic\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\nkey_light = bpy.context.active_object\nkey_light.name = \"KeyLight_WarmShaft\"\nkey_light.data.energy = 1200\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\nkey_light.data.size = 1.5\nkey_light.data.size_y = 2.5\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\n\n# Very subtle fill from right to prevent total blackness\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\nfill_light = bpy.context.active_object\nfill_light.name = \"FillLight_Dim\"\nfill_light.data.energy = 15\nfill_light.data.color = (0.5, 0.6, 0.8)\nfill_light.data.size = 4.0\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\n\n# Subtle warm rim from behind-right to separate objects\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\nrim_light = bpy.context.active_object\nrim_light.name = \"RimLight_Warm\"\nrim_light.data.energy = 40\nrim_light.data.color = (1.0, 0.75, 0.4)\nrim_light.data.size = 2.0\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\n\n# --- 2. Add a window frame to create light shaft pattern ---\n# Window frame (dark wood, partially visible on left)\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\nwindow_frame = bpy.context.active_object\nwindow_frame.name = \"WindowFrame\"\nwindow_frame.scale = (0.1, 2.0, 3.0)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\n\n# Assign dark wood material\nwindow_frame.data.materials.append(bpy.data.materials[\"M_TableTop\"])\n\n# --- 3. Adjust camera for better composition ---\ncam = bpy.data.objects[\"Camera_Presentation\"]\ncam.location = (3.5, -4.0, 2.0)\ntarget = Vector((-0.1, 0.0, 0.35))\ndirection = target - cam.location\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\ncam.data.dof.focus_distance = (cam.location - target).length\n\nprint(\"Lighting and camera refined.\")\nresult = {\"lights\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}
{"ts": "2026-07-17T15:10:48.827716+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:11:02.033695+00:00", "type": "llm_call", "call_index": 42, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:10:48.829222+00:00", "finished_at": "2026-07-17T15:11:02.033695+00:00", "duration_s": 13.203000000008615, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:10:48.829222+00:00", "finished_at": "2026-07-17T15:11:02.032691+00:00", "duration_s": 13.203000000008615, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "139436", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:10:52 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301050-wM3NOYhd9aJZYufmp3kW", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2cfa5a1541d1-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301050-wM3NOYhd9aJZYufmp3kW\",\"object\":\"chat.completion\",\"created\":1784301050,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-938e608ed2771955\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":37379,\"completion_tokens\":455,\"total_tokens\":37834,\"cost\":0.00847786236,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":36544,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00847786236,\"upstream_inference_prompt_cost\":0.00713852436,\"upstream_inference_completions_cost\":0.001339338},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTA1MC13TTNOT1loZDlhSlpZdWZtcDNrVyIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDEwNTAsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MzczNzksImNvbXBsZXRpb25fdG9rZW5zIjo0NTUsInRvdGFsX3Rva2VucyI6Mzc4MzQsImNvc3QiOjAuMDA4NDc3ODYyMzYsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MzY1NDQsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA4NDc3ODYyMzYsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDcxMzg1MjQzNiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAxMzM5MzM4fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Render preview with improved lighting\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.cycles.use_denoising = True\nscene.render.filepath = \"C:/tmp/still_life_preview3.png\"\nbpy.ops.render.render(write_still=True)\n\n# Analyze the result\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview3.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(f\"Image: {w}x{h}\")\nprint(\"\\nBrightness map (8x8 grid):\")\nfor gy in range(8):\n    row = \"\"\n    for gx in range(8):\n        x1 = gx * w // 8\n        x2 = (gx+1) * w // 8\n        y1 = gy * h // 8\n        y2 = (gy+1) * h // 8\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 20):\n            for x in range(x1, x2, 20):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.08: row += \"  \"\n        elif bright < 0.15: row += \"· \"\n        elif bright < 0.25: row += \"• \"\n        elif bright < 0.35: row += \"○ \"\n        elif bright < 0.45: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 37379, "tokens_out": 455, "cost_usd": 0.00847786236, "cached_tokens": 36544}, "error": null}
{"ts": "2026-07-17T15:11:02.036774+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Render preview with improved lighting\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.cycles.use_denoising = True\nscene.render.filepath = \"C:/tmp/still_life_preview3.png\"\nbpy.ops.render.render(write_still=True)\n\n# Analyze the result\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview3.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(f\"Image: {w}x{h}\")\nprint(\"\\nBrightness map (8x8 grid):\")\nfor gy in range(8):\n    row = \"\"\n    for gx in range(8):\n        x1 = gx * w // 8\n        x2 = (gx+1) * w // 8\n        y1 = gy * h // 8\n        y2 = (gy+1) * h // 8\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 20):\n            for x in range(x1, x2, 20):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.08: row += \"  \"\n        elif bright < 0.15: row += \"· \"\n        elif bright < 0.25: row += \"• \"\n        elif bright < 0.35: row += \"○ \"\n        elif bright < 0.45: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:11:02.036774+00:00", "type": "tool_call", "id": "chatcmpl-tool-938e608ed2771955", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Render preview with improved lighting\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.cycles.use_denoising = True\nscene.render.filepath = \"C:/tmp/still_life_preview3.png\"\nbpy.ops.render.render(write_still=True)\n\n# Analyze the result\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview3.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(f\"Image: {w}x{h}\")\nprint(\"\\nBrightness map (8x8 grid):\")\nfor gy in range(8):\n    row = \"\"\n    for gx in range(8):\n        x1 = gx * w // 8\n        x2 = (gx+1) * w // 8\n        y1 = gy * h // 8\n        y2 = (gy+1) * h // 8\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 20):\n            for x in range(x1, x2, 20):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.08: row += \"  \"\n        elif bright < 0.15: row += \"· \"\n        elif bright < 0.25: row += \"• \"\n        elif bright < 0.35: row += \"○ \"\n        elif bright < 0.45: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:11:28.969255+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:11:31.829840+00:00", "type": "llm_call", "call_index": 43, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:11:28.985782+00:00", "finished_at": "2026-07-17T15:11:31.829840+00:00", "duration_s": 2.8429999999934807, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:11:28.985782+00:00", "finished_at": "2026-07-17T15:11:31.829840+00:00", "duration_s": 2.8429999999934807, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "141721", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:11:31 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301089-UC3AOr328Q1GZJ9jHWay", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2df1fc927a1d-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301089-UC3AOr328Q1GZJ9jHWay\",\"object\":\"chat.completion\",\"created\":1784301089,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":38036,\"completion_tokens\":22,\"total_tokens\":38058,\"cost\":0.00718409664,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":37376,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00718409664,\"upstream_inference_prompt_cost\":0.00711933744,\"upstream_inference_completions_cost\":0.0000647592},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTA4OS1VQzNBT3IzMjhRMUdaSjlqSFdheSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDEwODksIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MzgwMzYsImNvbXBsZXRpb25fdG9rZW5zIjoyMiwidG90YWxfdG9rZW5zIjozODA1OCwiY29zdCI6MC4wMDcxODQwOTY2NCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjozNzM3NiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDcxODQwOTY2NCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNzExOTMzNzQ0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDAwNjQ3NTkyfSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}], "tokens_in": 38036, "tokens_out": 22, "cost_usd": 0.00718409664, "cached_tokens": 37376}, "error": null}
{"ts": "2026-07-17T15:11:31.833866+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:11:31.833866+00:00", "type": "tool_call", "id": "chatcmpl-tool-8421787e6475ccad", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}
{"ts": "2026-07-17T15:11:32.253247+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "name": "get_screenshot_of_area_as_image", "text": "", "is_error": false, "has_image": true, "image_b64": "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"}
{"ts": "2026-07-17T15:11:56.076206+00:00", "type": "llm_call", "call_index": 44, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:11:32.258256+00:00", "finished_at": "2026-07-17T15:11:56.076206+00:00", "duration_s": 23.82799999997951, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:11:32.258256+00:00", "finished_at": "2026-07-17T15:11:56.076206+00:00", "duration_s": 23.82799999997951, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "142007", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:11:35 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301093-ZnvcaifoLjlJpX5szbFS", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2e065812a6b0-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301093-ZnvcaifoLjlJpX5szbFS\",\"object\":\"chat.completion\",\"created\":1784301093,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":38062,\"completion_tokens\":899,\"total_tokens\":38961,\"cost\":0.00930188304,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":38016,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00930188304,\"upstream_inference_prompt_cost\":0.00665558664,\"upstream_inference_completions_cost\":0.0026462964},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDEwOTMtWm52Y2FpZm9MamxKcFg1c3piRlMiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAxMDkzLCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIGJyaWdodG5lc3MgbWFwIHNob3dzIHRoZSBvYmplY3RzIGFyZSBjb25jZW50cmF0ZWQgaW4gdGhlIGNlbnRlciB3aXRoIHRoZSB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQuIEkgY2FuIHNlZSB0aGUgdGFibGUgZWRnZSBhdCB0aGUgYm90dG9tIGFuZCB0aGUgY29tcG9zaXRpb24gaXMgZm9ybWluZy4gTGV0IG1lIG5vdyBtYWtlIHNpZ25pZmljYW50IHJlZmluZW1lbnRzOiBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwgdG8gYmUgbW9yZSBzaWx2ZXIvY2VyYW1pYywgZml4IHRoZSB3aW5lIGdsYXNzIHRvIGNvbnRhaW4gd2luZSwgYW5kIGVuaGFuY2UgdGhlIGNsb3RoIGRyYXBpbmcuIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWJmODE1ODU2MGZkNDgwZjYiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgVEVBUE9UIE1BVEVSSUFMOiBTaWx2ZXIvVmVybWVlciBjZXJhbWljIHdpdGggYWdlZCBwYXRpbmFcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGVhcG90U2lsdmVyXFxcIilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcblxcbiMgU2lsdmVyLWlzaCBiYXNlIHdpdGggd2FybSBjZXJhbWljIHVuZGVydG9uZXNcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MiwgMC43OCwgMC43MiwgMS4wKVxcbmJzZGYuaW5wdXRzWydNZXRhbGxpYyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjJcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcblxcbiMgQ29sb3IgdmFyaWF0aW9uOiBzaWx2ZXIgdG8gd2FybWVyIGJyb256ZSBhcmVhc1xcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgMjAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgwLCAyMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcyLCAwLjY2LCAwLjU1LCAxLjApICAjIHdhcm1lciBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44MiwgMC43NiwgMS4wKSAgIyBzaWx2ZXJcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgTWV0YWxsaWMgdmFyaWF0aW9uXFxuY29sb3JfcmFtcDIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgwLCAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAyLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcDIuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjUsIDAuNSwgMC41LCAxLjApICAjIGxlc3MgbWV0YWxsaWMgKGJyb256ZSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODUsIDAuODUsIDAuODUsIDEuMCkgICMgbW9yZSBtZXRhbGxpYyAoc2lsdmVyKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wMi5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snTWV0YWxsaWMnXSlcXG5cXG4jIFN1YnRsZSBzdXJmYWNlIGJ1bXAgZm9yIGFnZWQgZmVlbFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTE1MCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMVxcbm5vaXNlMyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xNTApKVxcbm5vaXNlMy5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDYwLjBcXG5ub2lzZTMuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuIyBBc3NpZ24gdG8gYWxsIHRlYXBvdCBwYXJ0c1xcbmZvciBuYW1lIGluIFtcXFwiVGVhcG90Qm9keVxcXCIsIFxcXCJUZWFwb3RTcG91dFxcXCIsIFxcXCJUZWFwb3RIYW5kbGVcXFwiLCBcXFwiVGVhcG90TGlkXFxcIl06XFxuICAgIG9iaiA9IGJweS5kYXRhLm9iamVjdHNbbmFtZV1cXG4gICAgb2JqLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG4gICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBSZW1vdmUgb2xkIG1hdGVyaWFsXFxub2xkID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5pZiBvbGQ6XFxuICAgIGJweS5kYXRhLm1hdGVyaWFscy5yZW1vdmUob2xkKVxcblxcbnByaW50KFxcXCJUZWFwb3Qgc2lsdmVyIG1hdGVyaWFsIGltcHJvdmVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjM4MDYyLCJjb21wbGV0aW9uX3Rva2VucyI6ODk5LCJ0b3RhbF90b2tlbnMiOjM4OTYxLCJjb3N0IjowLjAwOTMwMTg4MzA0LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjM4MDE2LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwOTMwMTg4MzA0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA2NjU1NTg2NjQsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMjY0NjI5NjR9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\n# ============================================================\nmat, nt = create_material(\"M_TeapotSilver\")\n\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\n\n# Silver-ish base with warm ceramic undertones\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\nbsdf.inputs['Metallic'].default_value = 0.7\nbsdf.inputs['Roughness'].default_value = 0.22\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n\n# Color variation: silver to warmer bronze areas\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\nnoise.inputs['Scale'].default_value = 6.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Metallic variation\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\n\n# Subtle surface bump for aged feel\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\nbump.inputs['Strength'].default_value = 0.1\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\nnoise3.inputs['Scale'].default_value = 60.0\nnoise3.inputs['Detail'].default_value = 8.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\n# Assign to all teapot parts\nfor name in [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]:\n    obj = bpy.data.objects[name]\n    obj.data.materials.clear()\n    obj.data.materials.append(mat)\n\n# Remove old material\nold = bpy.data.materials.get(\"M_TeapotCeramic\")\nif old:\n    bpy.data.materials.remove(old)\n\nprint(\"Teapot silver material improved.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 38062, "tokens_out": 899, "cost_usd": 0.00930188304, "cached_tokens": 38016}, "error": null}
{"ts": "2026-07-17T15:11:56.080930+00:00", "type": "assistant", "text": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\n# ============================================================\nmat, nt = create_material(\"M_TeapotSilver\")\n\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\n\n# Silver-ish base with warm ceramic undertones\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\nbsdf.inputs['Metallic'].default_value = 0.7\nbsdf.inputs['Roughness'].default_value = 0.22\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n\n# Color variation: silver to warmer bronze areas\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\nnoise.inputs['Scale'].default_value = 6.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Metallic variation\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\n\n# Subtle surface bump for aged feel\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\nbump.inputs['Strength'].default_value = 0.1\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\nnoise3.inputs['Scale'].default_value = 60.0\nnoise3.inputs['Detail'].default_value = 8.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\n# Assign to all teapot parts\nfor name in [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]:\n    obj = bpy.data.objects[name]\n    obj.data.materials.clear()\n    obj.data.materials.append(mat)\n\n# Remove old material\nold = bpy.data.materials.get(\"M_TeapotCeramic\")\nif old:\n    bpy.data.materials.remove(old)\n\nprint(\"Teapot silver material improved.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:11:56.080930+00:00", "type": "tool_call", "id": "chatcmpl-tool-bf8158560fd480f6", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\n# ============================================================\nmat, nt = create_material(\"M_TeapotSilver\")\n\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\n\n# Silver-ish base with warm ceramic undertones\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\nbsdf.inputs['Metallic'].default_value = 0.7\nbsdf.inputs['Roughness'].default_value = 0.22\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n\n# Color variation: silver to warmer bronze areas\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\nnoise.inputs['Scale'].default_value = 6.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Metallic variation\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\n\n# Subtle surface bump for aged feel\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\nbump.inputs['Strength'].default_value = 0.1\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\nnoise3.inputs['Scale'].default_value = 60.0\nnoise3.inputs['Detail'].default_value = 8.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\n# Assign to all teapot parts\nfor name in [\"TeapotBody\", \"TeapotSpout\", \"TeapotHandle\", \"TeapotLid\"]:\n    obj = bpy.data.objects[name]\n    obj.data.materials.clear()\n    obj.data.materials.append(mat)\n\n# Remove old material\nold = bpy.data.materials.get(\"M_TeapotCeramic\")\nif old:\n    bpy.data.materials.remove(old)\n\nprint(\"Teapot silver material improved.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:11:56.401969+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:12:20.238400+00:00", "type": "llm_call", "call_index": 45, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:11:56.402975+00:00", "finished_at": "2026-07-17T15:12:20.238400+00:00", "duration_s": 23.828999999997905, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:11:56.402975+00:00", "finished_at": "2026-07-17T15:12:20.237393+00:00", "duration_s": 23.828999999997905, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "145647", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:11:59 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301117-SQjZ9HDgyuu658jIzK3f", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2e9d4e19f783-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301117-SQjZ9HDgyuu658jIzK3f\",\"object\":\"chat.completion\",\"created\":1784301117,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":39001,\"completion_tokens\":914,\"total_tokens\":39915,\"cost\":0.01022550444,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":38016,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.01022550444,\"upstream_inference_prompt_cost\":0.00753505404,\"upstream_inference_completions_cost\":0.0026904504},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDExMTctU1FqWjlIRGd5dXU2NThqSXpLM2YiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAxMTE3LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjozOTAwMSwiY29tcGxldGlvbl90b2tlbnMiOjkxNCwidG90YWxfdG9rZW5zIjozOTkxNSwiY29zdCI6MC4wMTAyMjU1MDQ0NCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjozODAxNiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMTAyMjU1MDQ0NCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNzUzNTA1NDA0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDI2OTA0NTA0fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# IMPROVE WINE GLASS: Add red wine inside\n# ============================================================\n# Create a separate wine liquid mesh inside the glass\nimport bmesh\n\nmesh = bpy.data.meshes.new(\"WineLiquidMesh\")\nbm = bmesh.new()\n\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\nwine_profile = [\n    (0.00, 0.30),    # center bottom\n    (0.06, 0.30),    # \n    (0.08, 0.31),    # \n    (0.10, 0.32),    # \n    (0.11, 0.34),    # bowl\n    (0.12, 0.36),    # \n    (0.125, 0.38),   # \n    (0.12, 0.40),    # \n    (0.11, 0.42),    # \n    (0.10, 0.44),    # wine surface level\n    (0.00, 0.44),    # center top (wine surface)\n]\n\nsegments = 48\nall_verts = []\nfor r, h in wine_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = wine_profile[ri]\n    rb, _ = wine_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            # Cap the top (wine surface)\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nwine_obj = bpy.data.objects.new(\"WineLiquid\", mesh)\nbpy.context.scene.collection.objects.link(wine_obj)\nwine_obj.location = bpy.data.objects[\"WineGlass\"].location.copy()\nwine_obj.scale = bpy.data.objects[\"WineGlass\"].scale.copy()\nwine_obj.rotation_euler = bpy.data.objects[\"WineGlass\"].rotation_euler.copy()\n\n# Wine material - deep red, slightly translucent\nmat, nt = create_material(\"M_RedWine\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.1\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\nbsdf.inputs['Transmission Weight'].default_value = 0.3\nbsdf.inputs['IOR'].default_value = 1.33\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nwine_obj.data.materials.append(mat)\n\nprint(\"Wine liquid added to glass.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 39001, "tokens_out": 914, "cost_usd": 0.01022550444, "cached_tokens": 38016}, "error": null}
{"ts": "2026-07-17T15:12:20.242409+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# IMPROVE WINE GLASS: Add red wine inside\n# ============================================================\n# Create a separate wine liquid mesh inside the glass\nimport bmesh\n\nmesh = bpy.data.meshes.new(\"WineLiquidMesh\")\nbm = bmesh.new()\n\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\nwine_profile = [\n    (0.00, 0.30),    # center bottom\n    (0.06, 0.30),    # \n    (0.08, 0.31),    # \n    (0.10, 0.32),    # \n    (0.11, 0.34),    # bowl\n    (0.12, 0.36),    # \n    (0.125, 0.38),   # \n    (0.12, 0.40),    # \n    (0.11, 0.42),    # \n    (0.10, 0.44),    # wine surface level\n    (0.00, 0.44),    # center top (wine surface)\n]\n\nsegments = 48\nall_verts = []\nfor r, h in wine_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = wine_profile[ri]\n    rb, _ = wine_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            # Cap the top (wine surface)\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nwine_obj = bpy.data.objects.new(\"WineLiquid\", mesh)\nbpy.context.scene.collection.objects.link(wine_obj)\nwine_obj.location = bpy.data.objects[\"WineGlass\"].location.copy()\nwine_obj.scale = bpy.data.objects[\"WineGlass\"].scale.copy()\nwine_obj.rotation_euler = bpy.data.objects[\"WineGlass\"].rotation_euler.copy()\n\n# Wine material - deep red, slightly translucent\nmat, nt = create_material(\"M_RedWine\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.1\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\nbsdf.inputs['Transmission Weight'].default_value = 0.3\nbsdf.inputs['IOR'].default_value = 1.33\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nwine_obj.data.materials.append(mat)\n\nprint(\"Wine liquid added to glass.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:12:20.242409+00:00", "type": "tool_call", "id": "chatcmpl-tool-ae3e4ac817118e18", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# IMPROVE WINE GLASS: Add red wine inside\n# ============================================================\n# Create a separate wine liquid mesh inside the glass\nimport bmesh\n\nmesh = bpy.data.meshes.new(\"WineLiquidMesh\")\nbm = bmesh.new()\n\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\nwine_profile = [\n    (0.00, 0.30),    # center bottom\n    (0.06, 0.30),    # \n    (0.08, 0.31),    # \n    (0.10, 0.32),    # \n    (0.11, 0.34),    # bowl\n    (0.12, 0.36),    # \n    (0.125, 0.38),   # \n    (0.12, 0.40),    # \n    (0.11, 0.42),    # \n    (0.10, 0.44),    # wine surface level\n    (0.00, 0.44),    # center top (wine surface)\n]\n\nsegments = 48\nall_verts = []\nfor r, h in wine_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = wine_profile[ri]\n    rb, _ = wine_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            # Cap the top (wine surface)\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nwine_obj = bpy.data.objects.new(\"WineLiquid\", mesh)\nbpy.context.scene.collection.objects.link(wine_obj)\nwine_obj.location = bpy.data.objects[\"WineGlass\"].location.copy()\nwine_obj.scale = bpy.data.objects[\"WineGlass\"].scale.copy()\nwine_obj.rotation_euler = bpy.data.objects[\"WineGlass\"].rotation_euler.copy()\n\n# Wine material - deep red, slightly translucent\nmat, nt = create_material(\"M_RedWine\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.1\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\nbsdf.inputs['Transmission Weight'].default_value = 0.3\nbsdf.inputs['IOR'].default_value = 1.33\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nwine_obj.data.materials.append(mat)\n\nprint(\"Wine liquid added to glass.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:12:20.882019+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:12:42.262133+00:00", "type": "llm_call", "call_index": 46, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:12:20.882019+00:00", "finished_at": "2026-07-17T15:12:42.261128+00:00", "duration_s": 21.390999999974156, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:12:20.882019+00:00", "finished_at": "2026-07-17T15:12:42.261128+00:00", "duration_s": 21.390999999974156, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "149274", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:12:24 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301142-3087f9jcoRY8YNJ0A8jG", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2f383d57dd15-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301142-3087f9jcoRY8YNJ0A8jG\",\"object\":\"chat.completion\",\"created\":1784301142,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":39956,\"completion_tokens\":761,\"total_tokens\":40717,\"cost\":0.00993743304,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":38976,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00993743304,\"upstream_inference_prompt_cost\":0.00769735344,\"upstream_inference_completions_cost\":0.0022400796},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDExNDItMzA4N2Y5amNvUlk4WU5KMEE4akciLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAxMTQyLCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjozOTk1NiwiY29tcGxldGlvbl90b2tlbnMiOjc2MSwidG90YWxfdG9rZW5zIjo0MDcxNywiY29zdCI6MC4wMDk5Mzc0MzMwNCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjozODk3NiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDk5Mzc0MzMwNCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNzY5NzM1MzQ0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDIyNDAwNzk2fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector\n\nrandom.seed(7)\n\n# ============================================================\n# IMPROVE CLOTH FOLDS: More dramatic draping\n# ============================================================\n\n# Rebuild the red cloth with better draping (hanging off table edge)\nred_cloth = bpy.data.objects[\"RedCloth\"]\n# Remove and rebuild\nbpy.data.objects.remove(red_cloth, do_unlink=True)\nmat_red = bpy.data.materials[\"M_RedVelvet\"]\n\nmesh = bpy.data.meshes.new(\"RedClothMesh\")\nbm = bmesh.new()\n\n# Create a cloth that drapes over the left edge of the table\n# Grid of vertices\ncols = 50\nrows = 40\nwidth = 3.5\nlength = 3.5\n\nverts_grid = []\nfor ri in range(rows + 1):\n    row = []\n    for ci in range(cols + 1):\n        x = (ci / cols - 0.5) * width\n        y = (ri / rows - 0.5) * length\n        z = 0.0\n        \n        # Create folds: the cloth hangs off the front edge (y < -0.5)\n        # and has ripple folds on the table surface\n        if y < -0.5:\n            # Hanging down over the edge\n            edge_dist = abs(y + 0.5)\n            z = -edge_dist * 0.8\n            # Add vertical folds in the hanging part\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\n        else:\n            # On the table: gentle ripples\n            z = 0.02 * math.sin(x * 6 + y * 3)\n            z += 0.015 * math.cos(y * 8)\n        \n        # Add noise for natural variation\n        z += random.uniform(-0.01, 0.01)\n        \n        v = bm.verts.new((x, y, z))\n        row.append(v)\n    verts_grid.append(row)\n\n# Create faces\nfor ri in range(rows):\n    for ci in range(cols):\n        v1 = verts_grid[ri][ci]\n        v2 = verts_grid[ri][ci+1]\n        v3 = verts_grid[ri+1][ci+1]\n        v4 = verts_grid[ri+1][ci]\n        bm.faces.new([v1, v2, v3, v4])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nred_cloth = bpy.data.objects.new(\"RedCloth\", mesh)\nbpy.context.scene.collection.objects.link(red_cloth)\nred_cloth.location = (-1.8, -0.3, 0.01)\nbpy.context.view_layer.objects.active = red_cloth\nbpy.ops.object.shade_smooth()\n\n# Add solidify\nmod = red_cloth.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.012\nmod.offset = 0\n\n# Add subsurf for smoothness\nmod2 = red_cloth.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod2.levels = 1\nmod2.render_levels = 2\n\nred_cloth.data.materials.append(mat_red)\n\nprint(\"Red cloth rebuilt with better draping.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 39956, "tokens_out": 761, "cost_usd": 0.00993743304, "cached_tokens": 38976}, "error": null}
{"ts": "2026-07-17T15:12:42.265639+00:00", "type": "assistant", "text": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector\n\nrandom.seed(7)\n\n# ============================================================\n# IMPROVE CLOTH FOLDS: More dramatic draping\n# ============================================================\n\n# Rebuild the red cloth with better draping (hanging off table edge)\nred_cloth = bpy.data.objects[\"RedCloth\"]\n# Remove and rebuild\nbpy.data.objects.remove(red_cloth, do_unlink=True)\nmat_red = bpy.data.materials[\"M_RedVelvet\"]\n\nmesh = bpy.data.meshes.new(\"RedClothMesh\")\nbm = bmesh.new()\n\n# Create a cloth that drapes over the left edge of the table\n# Grid of vertices\ncols = 50\nrows = 40\nwidth = 3.5\nlength = 3.5\n\nverts_grid = []\nfor ri in range(rows + 1):\n    row = []\n    for ci in range(cols + 1):\n        x = (ci / cols - 0.5) * width\n        y = (ri / rows - 0.5) * length\n        z = 0.0\n        \n        # Create folds: the cloth hangs off the front edge (y < -0.5)\n        # and has ripple folds on the table surface\n        if y < -0.5:\n            # Hanging down over the edge\n            edge_dist = abs(y + 0.5)\n            z = -edge_dist * 0.8\n            # Add vertical folds in the hanging part\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\n        else:\n            # On the table: gentle ripples\n            z = 0.02 * math.sin(x * 6 + y * 3)\n            z += 0.015 * math.cos(y * 8)\n        \n        # Add noise for natural variation\n        z += random.uniform(-0.01, 0.01)\n        \n        v = bm.verts.new((x, y, z))\n        row.append(v)\n    verts_grid.append(row)\n\n# Create faces\nfor ri in range(rows):\n    for ci in range(cols):\n        v1 = verts_grid[ri][ci]\n        v2 = verts_grid[ri][ci+1]\n        v3 = verts_grid[ri+1][ci+1]\n        v4 = verts_grid[ri+1][ci]\n        bm.faces.new([v1, v2, v3, v4])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nred_cloth = bpy.data.objects.new(\"RedCloth\", mesh)\nbpy.context.scene.collection.objects.link(red_cloth)\nred_cloth.location = (-1.8, -0.3, 0.01)\nbpy.context.view_layer.objects.active = red_cloth\nbpy.ops.object.shade_smooth()\n\n# Add solidify\nmod = red_cloth.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.012\nmod.offset = 0\n\n# Add subsurf for smoothness\nmod2 = red_cloth.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod2.levels = 1\nmod2.render_levels = 2\n\nred_cloth.data.materials.append(mat_red)\n\nprint(\"Red cloth rebuilt with better draping.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:12:42.265639+00:00", "type": "tool_call", "id": "chatcmpl-tool-bf5e612aba0a0b79", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector\n\nrandom.seed(7)\n\n# ============================================================\n# IMPROVE CLOTH FOLDS: More dramatic draping\n# ============================================================\n\n# Rebuild the red cloth with better draping (hanging off table edge)\nred_cloth = bpy.data.objects[\"RedCloth\"]\n# Remove and rebuild\nbpy.data.objects.remove(red_cloth, do_unlink=True)\nmat_red = bpy.data.materials[\"M_RedVelvet\"]\n\nmesh = bpy.data.meshes.new(\"RedClothMesh\")\nbm = bmesh.new()\n\n# Create a cloth that drapes over the left edge of the table\n# Grid of vertices\ncols = 50\nrows = 40\nwidth = 3.5\nlength = 3.5\n\nverts_grid = []\nfor ri in range(rows + 1):\n    row = []\n    for ci in range(cols + 1):\n        x = (ci / cols - 0.5) * width\n        y = (ri / rows - 0.5) * length\n        z = 0.0\n        \n        # Create folds: the cloth hangs off the front edge (y < -0.5)\n        # and has ripple folds on the table surface\n        if y < -0.5:\n            # Hanging down over the edge\n            edge_dist = abs(y + 0.5)\n            z = -edge_dist * 0.8\n            # Add vertical folds in the hanging part\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\n        else:\n            # On the table: gentle ripples\n            z = 0.02 * math.sin(x * 6 + y * 3)\n            z += 0.015 * math.cos(y * 8)\n        \n        # Add noise for natural variation\n        z += random.uniform(-0.01, 0.01)\n        \n        v = bm.verts.new((x, y, z))\n        row.append(v)\n    verts_grid.append(row)\n\n# Create faces\nfor ri in range(rows):\n    for ci in range(cols):\n        v1 = verts_grid[ri][ci]\n        v2 = verts_grid[ri][ci+1]\n        v3 = verts_grid[ri+1][ci+1]\n        v4 = verts_grid[ri+1][ci]\n        bm.faces.new([v1, v2, v3, v4])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nred_cloth = bpy.data.objects.new(\"RedCloth\", mesh)\nbpy.context.scene.collection.objects.link(red_cloth)\nred_cloth.location = (-1.8, -0.3, 0.01)\nbpy.context.view_layer.objects.active = red_cloth\nbpy.ops.object.shade_smooth()\n\n# Add solidify\nmod = red_cloth.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.012\nmod.offset = 0\n\n# Add subsurf for smoothness\nmod2 = red_cloth.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod2.levels = 1\nmod2.render_levels = 2\n\nred_cloth.data.materials.append(mat_red)\n\nprint(\"Red cloth rebuilt with better draping.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:12:43.255160+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:13:00.047888+00:00", "type": "llm_call", "call_index": 47, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:12:43.269188+00:00", "finished_at": "2026-07-17T15:13:00.047888+00:00", "duration_s": 16.78100000001723, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:12:43.269188+00:00", "finished_at": "2026-07-17T15:13:00.046890+00:00", "duration_s": 16.78100000001723, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "152471", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:12:47 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301164-vCtYYdfXqrR0wkFnMgyV", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca2fc63ceb0d01-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301164-vCtYYdfXqrR0wkFnMgyV\",\"object\":\"chat.completion\",\"created\":1784301164,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-90e8b33148374071\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":40759,\"completion_tokens\":605,\"total_tokens\":41364,\"cost\":0.00949816764,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":39936,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00949816764,\"upstream_inference_prompt_cost\":0.00771728964,\"upstream_inference_completions_cost\":0.001780878},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDExNjQtdkN0WVlkZlhxclIwd2tGbk1neVYiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAxMTY0LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtOTBlOGIzMzE0ODM3NDA3MSIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDgpXFxuXFxuIyBSZWJ1aWxkIGdyZWVuIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmdcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmJweS5kYXRhLm9iamVjdHMucmVtb3ZlKGdyZWVuX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfZ3JlZW4gPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5WZWx2ZXRcXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJHcmVlbkNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy4wXFxubGVuZ3RoID0gMy4wXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBHcmVlbiBjbG90aCBvbiByaWdodCBzaWRlLCBkcmFwZWQgd2l0aCBmb2xkc1xcbiAgICAgICAgIyBUaGUgYmFjayBwYXJ0IHJpc2VzIHNsaWdodGx5IChhZ2FpbnN0IHRoZSB3YWxsKVxcbiAgICAgICAgaWYgeSA+IDAuODpcXG4gICAgICAgICAgICB6ID0gKHkgLSAwLjgpICogMC4zXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDUgKyB5ICogNClcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDcpXFxuICAgICAgICBcXG4gICAgICAgIHogKz0gcmFuZG9tLnVuaWZvcm0oLTAuMDA4LCAwLjAwOClcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyk6XFxuICAgIGZvciBjaSBpbiByYW5nZShjb2xzKTpcXG4gICAgICAgIHYxID0gdmVydHNfZ3JpZFtyaV1bY2ldXFxuICAgICAgICB2MiA9IHZlcnRzX2dyaWRbcmldW2NpKzFdXFxuICAgICAgICB2MyA9IHZlcnRzX2dyaWRbcmkrMV1bY2krMV1cXG4gICAgICAgIHY0ID0gdmVydHNfZ3JpZFtyaSsxXVtjaV1cXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbdjEsIHYyLCB2MywgdjRdKVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJHcmVlbkNsb3RoXFxcIiwgbWVzaClcXG5icHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhncmVlbl9jbG90aClcXG5ncmVlbl9jbG90aC5sb2NhdGlvbiA9ICgxLjgsIDAuNSwgMC4wMSlcXG5ncmVlbl9jbG90aC5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoLTUpKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBncmVlbl9jbG90aFxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxubW9kID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAxMlxcbm1vZC5vZmZzZXQgPSAwXFxuXFxubW9kMiA9IGdyZWVuX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfZ3JlZW4pXFxuXFxucHJpbnQoXFxcIkdyZWVuIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0MDc1OSwiY29tcGxldGlvbl90b2tlbnMiOjYwNSwidG90YWxfdG9rZW5zIjo0MTM2NCwiY29zdCI6MC4wMDk0OTgxNjc2NCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjozOTkzNiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDk0OTgxNjc2NCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNzcxNzI4OTY0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDE3ODA4Nzh9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector\n\nrandom.seed(8)\n\n# Rebuild green cloth with better draping\ngreen_cloth = bpy.data.objects[\"GreenCloth\"]\nbpy.data.objects.remove(green_cloth, do_unlink=True)\nmat_green = bpy.data.materials[\"M_GreenVelvet\"]\n\nmesh = bpy.data.meshes.new(\"GreenClothMesh\")\nbm = bmesh.new()\n\ncols = 40\nrows = 40\nwidth = 3.0\nlength = 3.0\n\nverts_grid = []\nfor ri in range(rows + 1):\n    row = []\n    for ci in range(cols + 1):\n        x = (ci / cols - 0.5) * width\n        y = (ri / rows - 0.5) * length\n        z = 0.0\n        \n        # Green cloth on right side, draped with folds\n        # The back part rises slightly (against the wall)\n        if y > 0.8:\n            z = (y - 0.8) * 0.3\n        else:\n            z = 0.02 * math.sin(x * 5 + y * 4)\n            z += 0.015 * math.cos(y * 7)\n        \n        z += random.uniform(-0.008, 0.008)\n        \n        v = bm.verts.new((x, y, z))\n        row.append(v)\n    verts_grid.append(row)\n\nfor ri in range(rows):\n    for ci in range(cols):\n        v1 = verts_grid[ri][ci]\n        v2 = verts_grid[ri][ci+1]\n        v3 = verts_grid[ri+1][ci+1]\n        v4 = verts_grid[ri+1][ci]\n        bm.faces.new([v1, v2, v3, v4])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\ngreen_cloth = bpy.data.objects.new(\"GreenCloth\", mesh)\nbpy.context.scene.collection.objects.link(green_cloth)\ngreen_cloth.location = (1.8, 0.5, 0.01)\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\nbpy.context.view_layer.objects.active = green_cloth\nbpy.ops.object.shade_smooth()\n\nmod = green_cloth.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.012\nmod.offset = 0\n\nmod2 = green_cloth.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod2.levels = 1\nmod2.render_levels = 2\n\ngreen_cloth.data.materials.append(mat_green)\n\nprint(\"Green cloth rebuilt with better draping.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 40759, "tokens_out": 605, "cost_usd": 0.00949816764, "cached_tokens": 39936}, "error": null}
{"ts": "2026-07-17T15:13:00.051393+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector\n\nrandom.seed(8)\n\n# Rebuild green cloth with better draping\ngreen_cloth = bpy.data.objects[\"GreenCloth\"]\nbpy.data.objects.remove(green_cloth, do_unlink=True)\nmat_green = bpy.data.materials[\"M_GreenVelvet\"]\n\nmesh = bpy.data.meshes.new(\"GreenClothMesh\")\nbm = bmesh.new()\n\ncols = 40\nrows = 40\nwidth = 3.0\nlength = 3.0\n\nverts_grid = []\nfor ri in range(rows + 1):\n    row = []\n    for ci in range(cols + 1):\n        x = (ci / cols - 0.5) * width\n        y = (ri / rows - 0.5) * length\n        z = 0.0\n        \n        # Green cloth on right side, draped with folds\n        # The back part rises slightly (against the wall)\n        if y > 0.8:\n            z = (y - 0.8) * 0.3\n        else:\n            z = 0.02 * math.sin(x * 5 + y * 4)\n            z += 0.015 * math.cos(y * 7)\n        \n        z += random.uniform(-0.008, 0.008)\n        \n        v = bm.verts.new((x, y, z))\n        row.append(v)\n    verts_grid.append(row)\n\nfor ri in range(rows):\n    for ci in range(cols):\n        v1 = verts_grid[ri][ci]\n        v2 = verts_grid[ri][ci+1]\n        v3 = verts_grid[ri+1][ci+1]\n        v4 = verts_grid[ri+1][ci]\n        bm.faces.new([v1, v2, v3, v4])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\ngreen_cloth = bpy.data.objects.new(\"GreenCloth\", mesh)\nbpy.context.scene.collection.objects.link(green_cloth)\ngreen_cloth.location = (1.8, 0.5, 0.01)\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\nbpy.context.view_layer.objects.active = green_cloth\nbpy.ops.object.shade_smooth()\n\nmod = green_cloth.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.012\nmod.offset = 0\n\nmod2 = green_cloth.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod2.levels = 1\nmod2.render_levels = 2\n\ngreen_cloth.data.materials.append(mat_green)\n\nprint(\"Green cloth rebuilt with better draping.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:13:00.051393+00:00", "type": "tool_call", "id": "chatcmpl-tool-90e8b33148374071", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector\n\nrandom.seed(8)\n\n# Rebuild green cloth with better draping\ngreen_cloth = bpy.data.objects[\"GreenCloth\"]\nbpy.data.objects.remove(green_cloth, do_unlink=True)\nmat_green = bpy.data.materials[\"M_GreenVelvet\"]\n\nmesh = bpy.data.meshes.new(\"GreenClothMesh\")\nbm = bmesh.new()\n\ncols = 40\nrows = 40\nwidth = 3.0\nlength = 3.0\n\nverts_grid = []\nfor ri in range(rows + 1):\n    row = []\n    for ci in range(cols + 1):\n        x = (ci / cols - 0.5) * width\n        y = (ri / rows - 0.5) * length\n        z = 0.0\n        \n        # Green cloth on right side, draped with folds\n        # The back part rises slightly (against the wall)\n        if y > 0.8:\n            z = (y - 0.8) * 0.3\n        else:\n            z = 0.02 * math.sin(x * 5 + y * 4)\n            z += 0.015 * math.cos(y * 7)\n        \n        z += random.uniform(-0.008, 0.008)\n        \n        v = bm.verts.new((x, y, z))\n        row.append(v)\n    verts_grid.append(row)\n\nfor ri in range(rows):\n    for ci in range(cols):\n        v1 = verts_grid[ri][ci]\n        v2 = verts_grid[ri][ci+1]\n        v3 = verts_grid[ri+1][ci+1]\n        v4 = verts_grid[ri+1][ci]\n        bm.faces.new([v1, v2, v3, v4])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\ngreen_cloth = bpy.data.objects.new(\"GreenCloth\", mesh)\nbpy.context.scene.collection.objects.link(green_cloth)\ngreen_cloth.location = (1.8, 0.5, 0.01)\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\nbpy.context.view_layer.objects.active = green_cloth\nbpy.ops.object.shade_smooth()\n\nmod = green_cloth.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.012\nmod.offset = 0\n\nmod2 = green_cloth.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod2.levels = 1\nmod2.render_levels = 2\n\ngreen_cloth.data.materials.append(mat_green)\n\nprint(\"Green cloth rebuilt with better draping.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:13:00.710400+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:13:26.905166+00:00", "type": "llm_call", "call_index": 48, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:13:00.712419+00:00", "finished_at": "2026-07-17T15:13:26.905166+00:00", "duration_s": 26.187000000005355, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:13:00.712419+00:00", "finished_at": "2026-07-17T15:13:26.904170+00:00", "duration_s": 26.187000000005355, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "154941", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:13:15 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301192-2bLHg2kRIQjbt1q0k2hw", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca3076ea760469-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301192-2bLHg2kRIQjbt1q0k2hw\",\"object\":\"chat.completion\",\"created\":1784301193,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":41406,\"completion_tokens\":577,\"total_tokens\":41983,\"cost\":0.00943600416,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":40704,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00943600416,\"upstream_inference_prompt_cost\":0.00773754696,\"upstream_inference_completions_cost\":0.0016984572},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDExOTItMmJMSGcya1JJUWpidDFxMGsyaHciLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAxMTkzLCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0MTQwNiwiY29tcGxldGlvbl90b2tlbnMiOjU3NywidG90YWxfdG9rZW5zIjo0MTk4MywiY29zdCI6MC4wMDk0MzYwMDQxNiwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjo0MDcwNCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDk0MzYwMDQxNiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwNzczNzU0Njk2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDE2OTg0NTcyfSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector\n\nrandom.seed(9)\n\n# Rebuild white/neutral linen runner\nwhite_cloth = bpy.data.objects[\"WhiteCloth\"]\nbpy.data.objects.remove(white_cloth, do_unlink=True)\nmat_white = bpy.data.materials[\"M_WhiteLinen\"]\n\nmesh = bpy.data.meshes.new(\"WhiteClothMesh\")\nbm = bmesh.new()\n\ncols = 40\nrows = 35\nwidth = 2.5\nlength = 2.2\n\nverts_grid = []\nfor ri in range(rows + 1):\n    row = []\n    for ci in range(cols + 1):\n        x = (ci / cols - 0.5) * width\n        y = (ri / rows - 0.5) * length\n        z = 0.0\n        \n        # Linen runner with subtle folds\n        z = 0.015 * math.sin(x * 4 + y * 2)\n        z += 0.01 * math.cos(y * 6)\n        # Slight droop at front edge\n        if y < -0.7:\n            z -= (abs(y) - 0.7) * 0.3\n        \n        z += random.uniform(-0.005, 0.005)\n        \n        v = bm.verts.new((x, y, z))\n        row.append(v)\n    verts_grid.append(row)\n\nfor ri in range(rows):\n    for ci in range(cols):\n        v1 = verts_grid[ri][ci]\n        v2 = verts_grid[ri][ci+1]\n        v3 = verts_grid[ri+1][ci+1]\n        v4 = verts_grid[ri+1][ci]\n        bm.faces.new([v1, v2, v3, v4])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nwhite_cloth = bpy.data.objects.new(\"WhiteCloth\", mesh)\nbpy.context.scene.collection.objects.link(white_cloth)\nwhite_cloth.location = (0.0, -0.1, 0.015)\nbpy.context.view_layer.objects.active = white_cloth\nbpy.ops.object.shade_smooth()\n\nmod = white_cloth.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.008\nmod.offset = 0\n\nmod2 = white_cloth.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod2.levels = 1\nmod2.render_levels = 2\n\nwhite_cloth.data.materials.append(mat_white)\n\nprint(\"White linen cloth rebuilt.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 41406, "tokens_out": 577, "cost_usd": 0.00943600416, "cached_tokens": 40704}, "error": null}
{"ts": "2026-07-17T15:13:26.909238+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector\n\nrandom.seed(9)\n\n# Rebuild white/neutral linen runner\nwhite_cloth = bpy.data.objects[\"WhiteCloth\"]\nbpy.data.objects.remove(white_cloth, do_unlink=True)\nmat_white = bpy.data.materials[\"M_WhiteLinen\"]\n\nmesh = bpy.data.meshes.new(\"WhiteClothMesh\")\nbm = bmesh.new()\n\ncols = 40\nrows = 35\nwidth = 2.5\nlength = 2.2\n\nverts_grid = []\nfor ri in range(rows + 1):\n    row = []\n    for ci in range(cols + 1):\n        x = (ci / cols - 0.5) * width\n        y = (ri / rows - 0.5) * length\n        z = 0.0\n        \n        # Linen runner with subtle folds\n        z = 0.015 * math.sin(x * 4 + y * 2)\n        z += 0.01 * math.cos(y * 6)\n        # Slight droop at front edge\n        if y < -0.7:\n            z -= (abs(y) - 0.7) * 0.3\n        \n        z += random.uniform(-0.005, 0.005)\n        \n        v = bm.verts.new((x, y, z))\n        row.append(v)\n    verts_grid.append(row)\n\nfor ri in range(rows):\n    for ci in range(cols):\n        v1 = verts_grid[ri][ci]\n        v2 = verts_grid[ri][ci+1]\n        v3 = verts_grid[ri+1][ci+1]\n        v4 = verts_grid[ri+1][ci]\n        bm.faces.new([v1, v2, v3, v4])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nwhite_cloth = bpy.data.objects.new(\"WhiteCloth\", mesh)\nbpy.context.scene.collection.objects.link(white_cloth)\nwhite_cloth.location = (0.0, -0.1, 0.015)\nbpy.context.view_layer.objects.active = white_cloth\nbpy.ops.object.shade_smooth()\n\nmod = white_cloth.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.008\nmod.offset = 0\n\nmod2 = white_cloth.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod2.levels = 1\nmod2.render_levels = 2\n\nwhite_cloth.data.materials.append(mat_white)\n\nprint(\"White linen cloth rebuilt.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:13:26.909238+00:00", "type": "tool_call", "id": "chatcmpl-tool-957c0db57cb79a8e", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nimport random\nfrom mathutils import Vector\n\nrandom.seed(9)\n\n# Rebuild white/neutral linen runner\nwhite_cloth = bpy.data.objects[\"WhiteCloth\"]\nbpy.data.objects.remove(white_cloth, do_unlink=True)\nmat_white = bpy.data.materials[\"M_WhiteLinen\"]\n\nmesh = bpy.data.meshes.new(\"WhiteClothMesh\")\nbm = bmesh.new()\n\ncols = 40\nrows = 35\nwidth = 2.5\nlength = 2.2\n\nverts_grid = []\nfor ri in range(rows + 1):\n    row = []\n    for ci in range(cols + 1):\n        x = (ci / cols - 0.5) * width\n        y = (ri / rows - 0.5) * length\n        z = 0.0\n        \n        # Linen runner with subtle folds\n        z = 0.015 * math.sin(x * 4 + y * 2)\n        z += 0.01 * math.cos(y * 6)\n        # Slight droop at front edge\n        if y < -0.7:\n            z -= (abs(y) - 0.7) * 0.3\n        \n        z += random.uniform(-0.005, 0.005)\n        \n        v = bm.verts.new((x, y, z))\n        row.append(v)\n    verts_grid.append(row)\n\nfor ri in range(rows):\n    for ci in range(cols):\n        v1 = verts_grid[ri][ci]\n        v2 = verts_grid[ri][ci+1]\n        v3 = verts_grid[ri+1][ci+1]\n        v4 = verts_grid[ri+1][ci]\n        bm.faces.new([v1, v2, v3, v4])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nwhite_cloth = bpy.data.objects.new(\"WhiteCloth\", mesh)\nbpy.context.scene.collection.objects.link(white_cloth)\nwhite_cloth.location = (0.0, -0.1, 0.015)\nbpy.context.view_layer.objects.active = white_cloth\nbpy.ops.object.shade_smooth()\n\nmod = white_cloth.modifiers.new(\"Solidify\", 'SOLIDIFY')\nmod.thickness = 0.008\nmod.offset = 0\n\nmod2 = white_cloth.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod2.levels = 1\nmod2.render_levels = 2\n\nwhite_cloth.data.materials.append(mat_white)\n\nprint(\"White linen cloth rebuilt.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:13:27.039849+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:13:39.146192+00:00", "type": "llm_call", "call_index": 49, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:13:27.111773+00:00", "finished_at": "2026-07-17T15:13:39.146192+00:00", "duration_s": 12.030999999988126, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:13:27.111773+00:00", "finished_at": "2026-07-17T15:13:39.145187+00:00", "duration_s": 12.030999999988126, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "157271", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:13:30 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301208-18aGlFjsFKiwu1ONP7nh", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca30d62c2fec95-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301208-18aGlFjsFKiwu1ONP7nh\",\"object\":\"chat.completion\",\"created\":1784301208,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-8f408822e950583f\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":42022,\"completion_tokens\":435,\"total_tokens\":42457,\"cost\":0.00910685616,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":41344,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00910685616,\"upstream_inference_prompt_cost\":0.00782639016,\"upstream_inference_completions_cost\":0.001280466},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxMjA4LTE4YUdsRmpzRktpd3UxT05QN25oIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTIwOCwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgcmVuZGVyIGEgcHJldmlldyB0byBjaGVjayB0aGUgaW1wcm92ZWQgY29tcG9zaXRpb24uIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLThmNDA4ODIyZTk1MDU4M2YiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG4jIEFuYWx5emVcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzQucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcXCIpXFxuZm9yIGd5IGluIHJhbmdlKDgpOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoOCk6XFxuICAgICAgICB4MSA9IGd4ICogdyAvLyA4XFxuICAgICAgICB4MiA9IChneCsxKSAqIHcgLy8gOFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gOFxcbiAgICAgICAgeTIgPSAoZ3krMSkgKiBoIC8vIDhcXG4gICAgICAgIGJyaWdodF9zdW0gPSAwXFxuICAgICAgICBjb3VudCA9IDBcXG4gICAgICAgIGZvciB5IGluIHJhbmdlKHkxLCB5MiwgMjApOlxcbiAgICAgICAgICAgIGZvciB4IGluIHJhbmdlKHgxLCB4MiwgMjApOlxcbiAgICAgICAgICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgICAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgICAgICAgICAgYnJpZ2h0X3N1bSArPSAocGl4ZWxzW2lkeF0gKyBwaXhlbHNbaWR4KzFdICsgcGl4ZWxzW2lkeCsyXSkgLyAzXFxuICAgICAgICAgICAgICAgICAgICBjb3VudCArPSAxXFxuICAgICAgICBicmlnaHQgPSBicmlnaHRfc3VtIC8gY291bnQgaWYgY291bnQgPiAwIGVsc2UgMFxcbiAgICAgICAgaWYgYnJpZ2h0IDwgMC4wODogcm93ICs9IFxcXCIgIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4xNTogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjU6IHJvdyArPSBcXFwi4oCiIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4zNTogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ1OiByb3cgKz0gXFxcIuKXjyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNTU6IHJvdyArPSBcXFwi4paTIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC43OiByb3cgKz0gXFxcIuKWkiBcXFwiXFxuICAgICAgICBlbHNlOiByb3cgKz0gXFxcIuKWiCBcXFwiXFxuICAgIHByaW50KGZcXFwiICBSb3cge2d5fTogfHtyb3d9fFxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjQyMDIyLCJjb21wbGV0aW9uX3Rva2VucyI6NDM1LCJ0b3RhbF90b2tlbnMiOjQyNDU3LCJjb3N0IjowLjAwOTEwNjg1NjE2LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjQxMzQ0LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwOTEwNjg1NjE2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA3ODI2MzkwMTYsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMTI4MDQ2Nn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview4.png\"\nbpy.ops.render.render(write_still=True)\n\n# Analyze\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview4.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (8x8 grid):\")\nfor gy in range(8):\n    row = \"\"\n    for gx in range(8):\n        x1 = gx * w // 8\n        x2 = (gx+1) * w // 8\n        y1 = gy * h // 8\n        y2 = (gy+1) * h // 8\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 20):\n            for x in range(x1, x2, 20):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.08: row += \"  \"\n        elif bright < 0.15: row += \"· \"\n        elif bright < 0.25: row += \"• \"\n        elif bright < 0.35: row += \"○ \"\n        elif bright < 0.45: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 42022, "tokens_out": 435, "cost_usd": 0.00910685616, "cached_tokens": 41344}, "error": null}
{"ts": "2026-07-17T15:13:39.150235+00:00", "type": "assistant", "text": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview4.png\"\nbpy.ops.render.render(write_still=True)\n\n# Analyze\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview4.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (8x8 grid):\")\nfor gy in range(8):\n    row = \"\"\n    for gx in range(8):\n        x1 = gx * w // 8\n        x2 = (gx+1) * w // 8\n        y1 = gy * h // 8\n        y2 = (gy+1) * h // 8\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 20):\n            for x in range(x1, x2, 20):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.08: row += \"  \"\n        elif bright < 0.15: row += \"· \"\n        elif bright < 0.25: row += \"• \"\n        elif bright < 0.35: row += \"○ \"\n        elif bright < 0.45: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:13:39.150235+00:00", "type": "tool_call", "id": "chatcmpl-tool-8f408822e950583f", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview4.png\"\nbpy.ops.render.render(write_still=True)\n\n# Analyze\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview4.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (8x8 grid):\")\nfor gy in range(8):\n    row = \"\"\n    for gx in range(8):\n        x1 = gx * w // 8\n        x2 = (gx+1) * w // 8\n        y1 = gy * h // 8\n        y2 = (gy+1) * h // 8\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 20):\n            for x in range(x1, x2, 20):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.08: row += \"  \"\n        elif bright < 0.15: row += \"· \"\n        elif bright < 0.25: row += \"• \"\n        elif bright < 0.35: row += \"○ \"\n        elif bright < 0.45: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:14:07.507991+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:14:11.822736+00:00", "type": "llm_call", "call_index": 50, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:14:07.508507+00:00", "finished_at": "2026-07-17T15:14:11.821737+00:00", "duration_s": 4.327999999979511, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:14:07.508507+00:00", "finished_at": "2026-07-17T15:14:11.820730+00:00", "duration_s": 4.312999999994645, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "159468", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:14:11 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301248-fgIM4tg6h2aOuxGgRrAO", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca31d0b9771bc0-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301248-fgIM4tg6h2aOuxGgRrAO\",\"object\":\"chat.completion\",\"created\":1784301248,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":42651,\"completion_tokens\":22,\"total_tokens\":42673,\"cost\":0.00799216836,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":41984,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00799216836,\"upstream_inference_prompt_cost\":0.00792740916,\"upstream_inference_completions_cost\":0.0000647592},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxMjQ4LWZnSU00dGc2aDJhT3V4R2dSckFPIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTI0OCwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0MjY1MSwiY29tcGxldGlvbl90b2tlbnMiOjIyLCJ0b3RhbF90b2tlbnMiOjQyNjczLCJjb3N0IjowLjAwNzk5MjE2ODM2LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjQxOTg0LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwNzk5MjE2ODM2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA3OTI3NDA5MTYsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMDA2NDc1OTJ9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}], "tokens_in": 42651, "tokens_out": 22, "cost_usd": 0.00799216836, "cached_tokens": 41984}, "error": null}
{"ts": "2026-07-17T15:14:11.827258+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:14:11.827258+00:00", "type": "tool_call", "id": "chatcmpl-tool-82aa10aa5a9e7a68", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}
{"ts": "2026-07-17T15:14:12.373460+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "name": "get_screenshot_of_area_as_image", "text": "", "is_error": false, "has_image": true, "image_b64": "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"}
{"ts": "2026-07-17T15:14:41.669017+00:00", "type": "llm_call", "call_index": 51, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:14:12.376973+00:00", "finished_at": "2026-07-17T15:14:41.668013+00:00", "duration_s": 29.296999999991385, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:14:12.376973+00:00", "finished_at": "2026-07-17T15:14:41.668013+00:00", "duration_s": 29.296999999991385, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "159754", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:14:15 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301253-AR4aLtZKt2MiYJFzlk53", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca31eef9a24e84-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301253-AR4aLtZKt2MiYJFzlk53\",\"object\":\"chat.completion\",\"created\":1784301253,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"refusal\":null,\"reasoning\":\"Let me analyze the brightness map. The composition seems to have objects in the center area, with some dark areas on the left. Let me think about what needs improvement:\\n\\n1. The left side (rows 0-1, columns 0-1) is quite dark - this might be where the red cloth drapes\\n2. The center has the objects (brightest area)\\n3. The right side has some brightness (green cloth/panel, wine glass, Suzanne)\\n\\nI should improve the composition further. Let me check the actual rendered image by taking a screenshot. Actually, let me just continue improving the scene and do a final render.\\n\\nKey improvements I should make:\\n1. Make sure all objects are clearly visible and well-positioned\\n2. Improve the checkered sphere material (it needs to be very reflective)\\n3. Make sure the Cornell box palette is clear (red left, green right, white center)\\n4. Improve lighting to create more dramatic chiaroscuro\\n5. Add more detail to the scene\\n\\nLet me check the teapot position and make sure it's the hero of the arrangement. Also, I should verify the Suzanne bust is properly set up - she should be \\\"gazing out of the arrangement.\\\"\\n\\nLet me also reconsider the camera angle. The task says \\\"camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\\\" Dutch still life paintings typically have a slightly elevated viewpoint, looking down at the table. My camera at (3.5, -4.0, 2.0) looking at (-0.1, 0.0, 0.35) should give that effect.\\n\\nLet me refine the composition and do another render.\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"Let me analyze the brightness map. The composition seems to have objects in the center area, with some dark areas on the left. Let me think about what needs improvement:\\n\\n1. The left side (rows 0-1, columns 0-1) is quite dark - this might be where the red cloth drapes\\n2. The center has the objects (brightest area)\\n3. The right side has some brightness (green cloth/panel, wine glass, Suzanne)\\n\\nI should improve the composition further. Let me check the actual rendered image by taking a screenshot. Actually, let me just continue improving the scene and do a final render.\\n\\nKey improvements I should make:\\n1. Make sure all objects are clearly visible and well-positioned\\n2. Improve the checkered sphere material (it needs to be very reflective)\\n3. Make sure the Cornell box palette is clear (red left, green right, white center)\\n4. Improve lighting to create more dramatic chiaroscuro\\n5. Add more detail to the scene\\n\\nLet me check the teapot position and make sure it's the hero of the arrangement. Also, I should verify the Suzanne bust is properly set up - she should be \\\"gazing out of the arrangement.\\\"\\n\\nLet me also reconsider the camera angle. The task says \\\"camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\\\" Dutch still life paintings typically have a slightly elevated viewpoint, looking down at the table. My camera at (3.5, -4.0, 2.0) looking at (-0.1, 0.0, 0.35) should give that effect.\\n\\nLet me refine the composition and do another render.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":42677,\"completion_tokens\":1173,\"total_tokens\":43850,\"cost\":0.01091650116,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":42624,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.01091650116,\"upstream_inference_prompt_cost\":0.00746365836,\"upstream_inference_completions_cost\":0.0034528428},\"completion_tokens_details\":{\"reasoning_tokens\":378,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTI1My1BUjRhTHRaS3QyTWlZSkZ6bGs1MyIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDEyNTMsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgcmVmaW5lIHRoZSBjb21wb3NpdGlvbiBhbmQgcG9zaXRpb25pbmcgb2Ygb2JqZWN0cywgdGhlbiBpbXByb3ZlIHRoZSBjaGVja2VyZWQgc3BoZXJlIHRvIGJlIG1vcmUgcmVmbGVjdGl2ZS4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOiJMZXQgbWUgYW5hbHl6ZSB0aGUgYnJpZ2h0bmVzcyBtYXAuIFRoZSBjb21wb3NpdGlvbiBzZWVtcyB0byBoYXZlIG9iamVjdHMgaW4gdGhlIGNlbnRlciBhcmVhLCB3aXRoIHNvbWUgZGFyayBhcmVhcyBvbiB0aGUgbGVmdC4gTGV0IG1lIHRoaW5rIGFib3V0IHdoYXQgbmVlZHMgaW1wcm92ZW1lbnQ6XG5cbjEuIFRoZSBsZWZ0IHNpZGUgKHJvd3MgMC0xLCBjb2x1bW5zIDAtMSkgaXMgcXVpdGUgZGFyayAtIHRoaXMgbWlnaHQgYmUgd2hlcmUgdGhlIHJlZCBjbG90aCBkcmFwZXNcbjIuIFRoZSBjZW50ZXIgaGFzIHRoZSBvYmplY3RzIChicmlnaHRlc3QgYXJlYSlcbjMuIFRoZSByaWdodCBzaWRlIGhhcyBzb21lIGJyaWdodG5lc3MgKGdyZWVuIGNsb3RoL3BhbmVsLCB3aW5lIGdsYXNzLCBTdXphbm5lKVxuXG5JIHNob3VsZCBpbXByb3ZlIHRoZSBjb21wb3NpdGlvbiBmdXJ0aGVyLiBMZXQgbWUgY2hlY2sgdGhlIGFjdHVhbCByZW5kZXJlZCBpbWFnZSBieSB0YWtpbmcgYSBzY3JlZW5zaG90LiBBY3R1YWxseSwgbGV0IG1lIGp1c3QgY29udGludWUgaW1wcm92aW5nIHRoZSBzY2VuZSBhbmQgZG8gYSBmaW5hbCByZW5kZXIuXG5cbktleSBpbXByb3ZlbWVudHMgSSBzaG91bGQgbWFrZTpcbjEuIE1ha2Ugc3VyZSBhbGwgb2JqZWN0cyBhcmUgY2xlYXJseSB2aXNpYmxlIGFuZCB3ZWxsLXBvc2l0aW9uZWRcbjIuIEltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgKGl0IG5lZWRzIHRvIGJlIHZlcnkgcmVmbGVjdGl2ZSlcbjMuIE1ha2Ugc3VyZSB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpcyBjbGVhciAocmVkIGxlZnQsIGdyZWVuIHJpZ2h0LCB3aGl0ZSBjZW50ZXIpXG40LiBJbXByb3ZlIGxpZ2h0aW5nIHRvIGNyZWF0ZSBtb3JlIGRyYW1hdGljIGNoaWFyb3NjdXJvXG41LiBBZGQgbW9yZSBkZXRhaWwgdG8gdGhlIHNjZW5lXG5cbkxldCBtZSBjaGVjayB0aGUgdGVhcG90IHBvc2l0aW9uIGFuZCBtYWtlIHN1cmUgaXQncyB0aGUgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQuIEFsc28sIEkgc2hvdWxkIHZlcmlmeSB0aGUgU3V6YW5uZSBidXN0IGlzIHByb3Blcmx5IHNldCB1cCAtIHNoZSBzaG91bGQgYmUgXCJnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cIlxuXG5MZXQgbWUgYWxzbyByZWNvbnNpZGVyIHRoZSBjYW1lcmEgYW5nbGUuIFRoZSB0YXNrIHNheXMgXCJjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuXCIgRHV0Y2ggc3RpbGwgbGlmZSBwYWludGluZ3MgdHlwaWNhbGx5IGhhdmUgYSBzbGlnaHRseSBlbGV2YXRlZCB2aWV3cG9pbnQsIGxvb2tpbmcgZG93biBhdCB0aGUgdGFibGUuIE15IGNhbWVyYSBhdCAoMy41LCAtNC4wLCAyLjApIGxvb2tpbmcgYXQgKC0wLjEsIDAuMCwgMC4zNSkgc2hvdWxkIGdpdmUgdGhhdCBlZmZlY3QuXG5cbkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBkbyBhbm90aGVyIHJlbmRlci4iLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWI0ZmJmYTYzM2JmZDI3YTYiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBSRVBPU0lUSU9OIE9CSkVDVFMgRk9SIEJFVFRFUiBDT01QT1NJVElPTlxcbiMgVGVhcG90IGlzIGhlcm8gKGNlbnRlciksIG92ZXJsYXBwaW5nIGRlcHRoIGFycmFuZ2VtZW50XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRlYXBvdCAtIGhlcm8sIGNlbnRlciwgY29tbWFuZGluZ1xcbnRlYXBvdCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlV0YWhUZWFwb3RcXFwiXVxcbnRlYXBvdC5sb2NhdGlvbiA9ICgwLjEsIDAuMCwgMC4wKVxcbnRlYXBvdC5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoLTIwKSlcXG50ZWFwb3Quc2NhbGUgPSAoMC45LCAwLjksIDAuOSlcXG5cXG4jIFN0YW5mb3JkIEJ1bm55IC0gbGVmdCBvZiB0ZWFwb3QsIHNsaWdodGx5IGJlaGluZFxcbmJ1bm55ID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiU3RhbmZvcmRCdW5ueVxcXCJdXFxuYnVubnkubG9jYXRpb24gPSAoLTEuMSwgMC4zLCAwLjAzKVxcbmJ1bm55LnJvdGF0aW9uX2V1bGVyID0gKDAsIG1hdGgucmFkaWFucygxMCksIG1hdGgucmFkaWFucygzNSkpXFxuYnVubnkuc2NhbGUgPSAoMS4yLCAxLjIsIDEuMilcXG5cXG4jIFN1emFubmUgLSByaWdodCBzaWRlLCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXRcXG5zdXphbm5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiU3V6YW5uZVxcXCJdXFxuc3V6YW5uZS5sb2NhdGlvbiA9ICgxLjEsIC0wLjEsIDAuMilcXG5zdXphbm5lLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxMCksIG1hdGgucmFkaWFucygtNSksIG1hdGgucmFkaWFucyg3NSkpXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjA0KVxcblxcbiMgQ2hlY2tlcmVkIHNwaGVyZSAtIGZyb250LWNlbnRlciwgc2xpZ2h0bHkgdG8gcmlnaHQgb2YgdGVhcG90XFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4zLCAtMC43LCAwLjIyKVxcblxcbiMgV2luZSBnbGFzcyAtIGZhciByaWdodCwgYmVoaW5kIFN1emFubmVcXG5nbGFzcyA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdXFxuZ2xhc3MubG9jYXRpb24gPSAoMS43LCAwLjUsIDAuMClcXG5nbGFzcy5zY2FsZSA9ICgxLjEsIDEuMSwgMS4xKVxcblxcbndpbmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lTGlxdWlkXFxcIl1cXG53aW5lLmxvY2F0aW9uID0gZ2xhc3MubG9jYXRpb24uY29weSgpXFxud2luZS5zY2FsZSA9IGdsYXNzLnNjYWxlLmNvcHkoKVxcblxcbiMgT3BlbiBib29rIC0gbGVmdC1mcm9udCwgcGFydGlhbGx5IHVuZGVyIGJ1bm55XFxuYm9vayA9IGJweS5kYXRhLm9iamVjdHNbXFxcIk9wZW5Cb29rXFxcIl1cXG5ib29rLmxvY2F0aW9uID0gKC0wLjUsIC0wLjgsIDAuMDIpXFxuYm9vay5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbmNvdmVyID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQm9va0NvdmVyXFxcIl1cXG5jb3Zlci5sb2NhdGlvbiA9IGJvb2subG9jYXRpb24uY29weSgpXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgRnJ1aXQgY2x1c3RlciAtIGZyb250LXJpZ2h0LCBuZWFyIFN1emFubmVcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC45LCAtMC44LCAwLjA5KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIk9yYW5nZTFcXFwiXS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoMzApKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIk9yYW5nZTJcXFwiXS5sb2NhdGlvbiA9ICgxLjEsIC0wLjcsIDAuMDc1KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIk9yYW5nZTJcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMjApLCAwLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLmxvY2F0aW9uID0gKDAuNzUsIC0wLjY1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg1MCkpXFxuXFxuIyBDYW1lcmEgLSBzbGlnaHRseSBlbGV2YXRlZCwgNTBtbSBlcXVpdmFsZW50XFxuY2FtID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FtZXJhX1ByZXNlbnRhdGlvblxcXCJdXFxuY2FtLmxvY2F0aW9uID0gKDMuMiwgLTQuMiwgMi4wKVxcbnRhcmdldCA9IFZlY3RvcigoMC4xLCAtMC4xLCAwLjM1KSlcXG5kaXJlY3Rpb24gPSB0YXJnZXQgLSBjYW0ubG9jYXRpb25cXG5yb3RfcXVhdCA9IGRpcmVjdGlvbi50b190cmFja19xdWF0KCctWicsICdZJylcXG5jYW0ucm90YXRpb25fZXVsZXIgPSByb3RfcXVhdC50b19ldWxlcigpXFxuY2FtLmRhdGEuZG9mLmZvY3VzX2Rpc3RhbmNlID0gKGNhbS5sb2NhdGlvbiAtIHRhcmdldCkubGVuZ3RoXFxuXFxucHJpbnQoXFxcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dLCJyZWFzb25pbmdfZGV0YWlscyI6W3sidHlwZSI6InJlYXNvbmluZy50ZXh0IiwidGV4dCI6IkxldCBtZSBhbmFseXplIHRoZSBicmlnaHRuZXNzIG1hcC4gVGhlIGNvbXBvc2l0aW9uIHNlZW1zIHRvIGhhdmUgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFyZWEsIHdpdGggc29tZSBkYXJrIGFyZWFzIG9uIHRoZSBsZWZ0LiBMZXQgbWUgdGhpbmsgYWJvdXQgd2hhdCBuZWVkcyBpbXByb3ZlbWVudDpcblxuMS4gVGhlIGxlZnQgc2lkZSAocm93cyAwLTEsIGNvbHVtbnMgMC0xKSBpcyBxdWl0ZSBkYXJrIC0gdGhpcyBtaWdodCBiZSB3aGVyZSB0aGUgcmVkIGNsb3RoIGRyYXBlc1xuMi4gVGhlIGNlbnRlciBoYXMgdGhlIG9iamVjdHMgKGJyaWdodGVzdCBhcmVhKVxuMy4gVGhlIHJpZ2h0IHNpZGUgaGFzIHNvbWUgYnJpZ2h0bmVzcyAoZ3JlZW4gY2xvdGgvcGFuZWwsIHdpbmUgZ2xhc3MsIFN1emFubmUpXG5cbkkgc2hvdWxkIGltcHJvdmUgdGhlIGNvbXBvc2l0aW9uIGZ1cnRoZXIuIExldCBtZSBjaGVjayB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIGJ5IHRha2luZyBhIHNjcmVlbnNob3QuIEFjdHVhbGx5LCBsZXQgbWUganVzdCBjb250aW51ZSBpbXByb3ZpbmcgdGhlIHNjZW5lIGFuZCBkbyBhIGZpbmFsIHJlbmRlci5cblxuS2V5IGltcHJvdmVtZW50cyBJIHNob3VsZCBtYWtlOlxuMS4gTWFrZSBzdXJlIGFsbCBvYmplY3RzIGFyZSBjbGVhcmx5IHZpc2libGUgYW5kIHdlbGwtcG9zaXRpb25lZFxuMi4gSW1wcm92ZSB0aGUgY2hlY2tlcmVkIHNwaGVyZSBtYXRlcmlhbCAoaXQgbmVlZHMgdG8gYmUgdmVyeSByZWZsZWN0aXZlKVxuMy4gTWFrZSBzdXJlIHRoZSBDb3JuZWxsIGJveCBwYWxldHRlIGlzIGNsZWFyIChyZWQgbGVmdCwgZ3JlZW4gcmlnaHQsIHdoaXRlIGNlbnRlcilcbjQuIEltcHJvdmUgbGlnaHRpbmcgdG8gY3JlYXRlIG1vcmUgZHJhbWF0aWMgY2hpYXJvc2N1cm9cbjUuIEFkZCBtb3JlIGRldGFpbCB0byB0aGUgc2NlbmVcblxuTGV0IG1lIGNoZWNrIHRoZSB0ZWFwb3QgcG9zaXRpb24gYW5kIG1ha2Ugc3VyZSBpdCdzIHRoZSBoZXJvIG9mIHRoZSBhcnJhbmdlbWVudC4gQWxzbywgSSBzaG91bGQgdmVyaWZ5IHRoZSBTdXphbm5lIGJ1c3QgaXMgcHJvcGVybHkgc2V0IHVwIC0gc2hlIHNob3VsZCBiZSBcImdhemluZyBvdXQgb2YgdGhlIGFycmFuZ2VtZW50LlwiXG5cbkxldCBtZSBhbHNvIHJlY29uc2lkZXIgdGhlIGNhbWVyYSBhbmdsZS4gVGhlIHRhc2sgc2F5cyBcImNhbWVyYSBhdCB0aGUgaW50aW1hdGUgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUgb2YgdGhlIGdlbnJlLCByb3VnaGx5IDUwbW0gZXF1aXZhbGVudC5cIiBEdXRjaCBzdGlsbCBsaWZlIHBhaW50aW5ncyB0eXBpY2FsbHkgaGF2ZSBhIHNsaWdodGx5IGVsZXZhdGVkIHZpZXdwb2ludCwgbG9va2luZyBkb3duIGF0IHRoZSB0YWJsZS4gTXkgY2FtZXJhIGF0ICgzLjUsIC00LjAsIDIuMCkgbG9va2luZyBhdCAoLTAuMSwgMC4wLCAwLjM1KSBzaG91bGQgZ2l2ZSB0aGF0IGVmZmVjdC5cblxuTGV0IG1lIHJlZmluZSB0aGUgY29tcG9zaXRpb24gYW5kIGRvIGFub3RoZXIgcmVuZGVyLiIsImZvcm1hdCI6InVua25vd24iLCJpbmRleCI6MH1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0MjY3NywiY29tcGxldGlvbl90b2tlbnMiOjExNzMsInRvdGFsX3Rva2VucyI6NDM4NTAsImNvc3QiOjAuMDEwOTE2NTAxMTYsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6NDI2MjQsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDEwOTE2NTAxMTYsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDc0NjM2NTgzNiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAzNDUyODQyOH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6Mzc4LCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\n# Teapot is hero (center), overlapping depth arrangement\n# ============================================================\n\n# Teapot - hero, center, commanding\nteapot = bpy.data.objects[\"UtahTeapot\"]\nteapot.location = (0.1, 0.0, 0.0)\nteapot.rotation_euler = (0, 0, math.radians(-20))\nteapot.scale = (0.9, 0.9, 0.9)\n\n# Stanford Bunny - left of teapot, slightly behind\nbunny = bpy.data.objects[\"StanfordBunny\"]\nbunny.location = (-1.1, 0.3, 0.03)\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\nbunny.scale = (1.2, 1.2, 1.2)\n\n# Suzanne - right side, as bust portrait gazing out\nsuzanne = bpy.data.objects[\"Suzanne\"]\nsuzanne.location = (1.1, -0.1, 0.2)\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\n\nbase = bpy.data.objects[\"SuzanneBase\"]\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\n\n# Checkered sphere - front-center, slightly to right of teapot\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nsphere.location = (0.3, -0.7, 0.22)\n\n# Wine glass - far right, behind Suzanne\nglass = bpy.data.objects[\"WineGlass\"]\nglass.location = (1.7, 0.5, 0.0)\nglass.scale = (1.1, 1.1, 1.1)\n\nwine = bpy.data.objects[\"WineLiquid\"]\nwine.location = glass.location.copy()\nwine.scale = glass.scale.copy()\n\n# Open book - left-front, partially under bunny\nbook = bpy.data.objects[\"OpenBook\"]\nbook.location = (-0.5, -0.8, 0.02)\nbook.rotation_euler = (0, 0, math.radians(20))\n\ncover = bpy.data.objects[\"BookCover\"]\ncover.location = book.location.copy()\ncover.rotation_euler = book.rotation_euler.copy()\n\n# Fruit cluster - front-right, near Suzanne\nbpy.data.objects[\"Orange1\"].location = (0.9, -0.8, 0.09)\nbpy.data.objects[\"Orange1\"].rotation_euler = (0, 0, math.radians(30))\n\nbpy.data.objects[\"Orange2\"].location = (1.1, -0.7, 0.075)\nbpy.data.objects[\"Orange2\"].rotation_euler = (math.radians(20), 0, math.radians(15))\n\nbpy.data.objects[\"Lemon1\"].location = (0.75, -0.65, 0.08)\nbpy.data.objects[\"Lemon1\"].rotation_euler = (math.radians(15), 0, math.radians(50))\n\n# Camera - slightly elevated, 50mm equivalent\ncam = bpy.data.objects[\"Camera_Presentation\"]\ncam.location = (3.2, -4.2, 2.0)\ntarget = Vector((0.1, -0.1, 0.35))\ndirection = target - cam.location\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\ncam.data.dof.focus_distance = (cam.location - target).length\n\nprint(\"Objects repositioned for composition.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 42677, "tokens_out": 1173, "cost_usd": 0.01091650116, "cached_tokens": 42624}, "error": null}
{"ts": "2026-07-17T15:14:41.673529+00:00", "type": "assistant", "text": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\n# Teapot is hero (center), overlapping depth arrangement\n# ============================================================\n\n# Teapot - hero, center, commanding\nteapot = bpy.data.objects[\"UtahTeapot\"]\nteapot.location = (0.1, 0.0, 0.0)\nteapot.rotation_euler = (0, 0, math.radians(-20))\nteapot.scale = (0.9, 0.9, 0.9)\n\n# Stanford Bunny - left of teapot, slightly behind\nbunny = bpy.data.objects[\"StanfordBunny\"]\nbunny.location = (-1.1, 0.3, 0.03)\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\nbunny.scale = (1.2, 1.2, 1.2)\n\n# Suzanne - right side, as bust portrait gazing out\nsuzanne = bpy.data.objects[\"Suzanne\"]\nsuzanne.location = (1.1, -0.1, 0.2)\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\n\nbase = bpy.data.objects[\"SuzanneBase\"]\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\n\n# Checkered sphere - front-center, slightly to right of teapot\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nsphere.location = (0.3, -0.7, 0.22)\n\n# Wine glass - far right, behind Suzanne\nglass = bpy.data.objects[\"WineGlass\"]\nglass.location = (1.7, 0.5, 0.0)\nglass.scale = (1.1, 1.1, 1.1)\n\nwine = bpy.data.objects[\"WineLiquid\"]\nwine.location = glass.location.copy()\nwine.scale = glass.scale.copy()\n\n# Open book - left-front, partially under bunny\nbook = bpy.data.objects[\"OpenBook\"]\nbook.location = (-0.5, -0.8, 0.02)\nbook.rotation_euler = (0, 0, math.radians(20))\n\ncover = bpy.data.objects[\"BookCover\"]\ncover.location = book.location.copy()\ncover.rotation_euler = book.rotation_euler.copy()\n\n# Fruit cluster - front-right, near Suzanne\nbpy.data.objects[\"Orange1\"].location = (0.9, -0.8, 0.09)\nbpy.data.objects[\"Orange1\"].rotation_euler = (0, 0, math.radians(30))\n\nbpy.data.objects[\"Orange2\"].location = (1.1, -0.7, 0.075)\nbpy.data.objects[\"Orange2\"].rotation_euler = (math.radians(20), 0, math.radians(15))\n\nbpy.data.objects[\"Lemon1\"].location = (0.75, -0.65, 0.08)\nbpy.data.objects[\"Lemon1\"].rotation_euler = (math.radians(15), 0, math.radians(50))\n\n# Camera - slightly elevated, 50mm equivalent\ncam = bpy.data.objects[\"Camera_Presentation\"]\ncam.location = (3.2, -4.2, 2.0)\ntarget = Vector((0.1, -0.1, 0.35))\ndirection = target - cam.location\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\ncam.data.dof.focus_distance = (cam.location - target).length\n\nprint(\"Objects repositioned for composition.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:14:41.673529+00:00", "type": "tool_call", "id": "chatcmpl-tool-b4fbfa633bfd27a6", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\n# Teapot is hero (center), overlapping depth arrangement\n# ============================================================\n\n# Teapot - hero, center, commanding\nteapot = bpy.data.objects[\"UtahTeapot\"]\nteapot.location = (0.1, 0.0, 0.0)\nteapot.rotation_euler = (0, 0, math.radians(-20))\nteapot.scale = (0.9, 0.9, 0.9)\n\n# Stanford Bunny - left of teapot, slightly behind\nbunny = bpy.data.objects[\"StanfordBunny\"]\nbunny.location = (-1.1, 0.3, 0.03)\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\nbunny.scale = (1.2, 1.2, 1.2)\n\n# Suzanne - right side, as bust portrait gazing out\nsuzanne = bpy.data.objects[\"Suzanne\"]\nsuzanne.location = (1.1, -0.1, 0.2)\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\n\nbase = bpy.data.objects[\"SuzanneBase\"]\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\n\n# Checkered sphere - front-center, slightly to right of teapot\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nsphere.location = (0.3, -0.7, 0.22)\n\n# Wine glass - far right, behind Suzanne\nglass = bpy.data.objects[\"WineGlass\"]\nglass.location = (1.7, 0.5, 0.0)\nglass.scale = (1.1, 1.1, 1.1)\n\nwine = bpy.data.objects[\"WineLiquid\"]\nwine.location = glass.location.copy()\nwine.scale = glass.scale.copy()\n\n# Open book - left-front, partially under bunny\nbook = bpy.data.objects[\"OpenBook\"]\nbook.location = (-0.5, -0.8, 0.02)\nbook.rotation_euler = (0, 0, math.radians(20))\n\ncover = bpy.data.objects[\"BookCover\"]\ncover.location = book.location.copy()\ncover.rotation_euler = book.rotation_euler.copy()\n\n# Fruit cluster - front-right, near Suzanne\nbpy.data.objects[\"Orange1\"].location = (0.9, -0.8, 0.09)\nbpy.data.objects[\"Orange1\"].rotation_euler = (0, 0, math.radians(30))\n\nbpy.data.objects[\"Orange2\"].location = (1.1, -0.7, 0.075)\nbpy.data.objects[\"Orange2\"].rotation_euler = (math.radians(20), 0, math.radians(15))\n\nbpy.data.objects[\"Lemon1\"].location = (0.75, -0.65, 0.08)\nbpy.data.objects[\"Lemon1\"].rotation_euler = (math.radians(15), 0, math.radians(50))\n\n# Camera - slightly elevated, 50mm equivalent\ncam = bpy.data.objects[\"Camera_Presentation\"]\ncam.location = (3.2, -4.2, 2.0)\ntarget = Vector((0.1, -0.1, 0.35))\ndirection = target - cam.location\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\ncam.data.dof.focus_distance = (cam.location - target).length\n\nprint(\"Objects repositioned for composition.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:14:42.461025+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:14:58.819009+00:00", "type": "llm_call", "call_index": 52, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:14:42.503194+00:00", "finished_at": "2026-07-17T15:14:58.817494+00:00", "duration_s": 16.312999999994645, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:14:42.503194+00:00", "finished_at": "2026-07-17T15:14:58.817494+00:00", "duration_s": 16.312999999994645, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "163091", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:14:48 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301285-eF0l8H9ixZiHkfoPjQ4Y", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca32b73eaaf771-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301285-eF0l8H9ixZiHkfoPjQ4Y\",\"object\":\"chat.completion\",\"created\":1784301285,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":43543,\"completion_tokens\":426,\"total_tokens\":43969,\"cost\":0.00952872756,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":42624,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00952872756,\"upstream_inference_prompt_cost\":0.00827475396,\"upstream_inference_completions_cost\":0.0012539736},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxMjg1LWVGMGw4SDlpeFppSGtmb1BqUTRZIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTI4NSwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLTkxYmY0YTFhOWI3MjkwMWQiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbiMgUXVpY2sgcmVuZGVyIHRvIGNoZWNrIGNvbXBvc2l0aW9uXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NS5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxucHJpbnQoXFxcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSgxMCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSgxMCk6XFxuICAgICAgICB4MSA9IGd4ICogdyAvLyAxMFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDEwXFxuICAgICAgICB5MSA9IGd5ICogaCAvLyAxMFxcbiAgICAgICAgeTIgPSAoZ3krMSkgKiBoIC8vIDEwXFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDI1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDI1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDY6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTI6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI6IHJvdyArPSBcXFwi4oCiIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4zOiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU6IHJvdyArPSBcXFwi4paTIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC42NTogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0MzU0MywiY29tcGxldGlvbl90b2tlbnMiOjQyNiwidG90YWxfdG9rZW5zIjo0Mzk2OSwiY29zdCI6MC4wMDk1Mjg3Mjc1NiwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjo0MjYyNCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDk1Mjg3Mjc1NiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwODI3NDc1Mzk2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDEyNTM5NzM2fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Quick render to check composition\nscene = bpy.context.scene\nscene.cycles.samples = 24\nscene.render.filepath = \"C:/tmp/still_life_preview5.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview5.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (10x10 grid):\")\nfor gy in range(10):\n    row = \"\"\n    for gx in range(10):\n        x1 = gx * w // 10\n        x2 = (gx+1) * w // 10\n        y1 = gy * h // 10\n        y2 = (gy+1) * h // 10\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 25):\n            for x in range(x1, x2, 25):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.5: row += \"▓ \"\n        elif bright < 0.65: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 43543, "tokens_out": 426, "cost_usd": 0.00952872756, "cached_tokens": 42624}, "error": null}
{"ts": "2026-07-17T15:14:58.825025+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Quick render to check composition\nscene = bpy.context.scene\nscene.cycles.samples = 24\nscene.render.filepath = \"C:/tmp/still_life_preview5.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview5.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (10x10 grid):\")\nfor gy in range(10):\n    row = \"\"\n    for gx in range(10):\n        x1 = gx * w // 10\n        x2 = (gx+1) * w // 10\n        y1 = gy * h // 10\n        y2 = (gy+1) * h // 10\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 25):\n            for x in range(x1, x2, 25):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.5: row += \"▓ \"\n        elif bright < 0.65: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:14:58.825025+00:00", "type": "tool_call", "id": "chatcmpl-tool-91bf4a1a9b72901d", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Quick render to check composition\nscene = bpy.context.scene\nscene.cycles.samples = 24\nscene.render.filepath = \"C:/tmp/still_life_preview5.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview5.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (10x10 grid):\")\nfor gy in range(10):\n    row = \"\"\n    for gx in range(10):\n        x1 = gx * w // 10\n        x2 = (gx+1) * w // 10\n        y1 = gy * h // 10\n        y2 = (gy+1) * h // 10\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 25):\n            for x in range(x1, x2, 25):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.5: row += \"▓ \"\n        elif bright < 0.65: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:15:23.058132+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:15:38.555355+00:00", "type": "llm_call", "call_index": 53, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:15:23.059132+00:00", "finished_at": "2026-07-17T15:15:38.554357+00:00", "duration_s": 15.48399999999674, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:15:23.059132+00:00", "finished_at": "2026-07-17T15:15:38.554357+00:00", "duration_s": 15.48399999999674, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "165421", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:15:37 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301335-isUsDolycIF395lagE8h", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca33ee3e34032d-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301335-isUsDolycIF395lagE8h\",\"object\":\"chat.completion\",\"created\":1784301335,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":44227,\"completion_tokens\":72,\"total_tokens\":44299,\"cost\":0.0084439842,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":43520,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0084439842,\"upstream_inference_prompt_cost\":0.008232045,\"upstream_inference_completions_cost\":0.0002119392},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxMzM1LWlzVXNEb2x5Y0lGMzk1bGFnRThoIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTMzNSwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6NDQyMjcsImNvbXBsZXRpb25fdG9rZW5zIjo3MiwidG90YWxfdG9rZW5zIjo0NDI5OSwiY29zdCI6MC4wMDg0NDM5ODQyLCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjQzNTIwLCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwODQ0Mzk4NDIsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDgyMzIwNDUsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMDIxMTkzOTJ9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}], "tokens_in": 44227, "tokens_out": 72, "cost_usd": 0.0084439842, "cached_tokens": 43520}, "error": null}
{"ts": "2026-07-17T15:15:38.558929+00:00", "type": "assistant", "text": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:15:38.558929+00:00", "type": "tool_call", "id": "chatcmpl-tool-a3cf445099275d43", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}
{"ts": "2026-07-17T15:15:41.489247+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "name": "get_screenshot_of_area_as_image", "text": "", "is_error": false, "has_image": true, "image_b64": "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"}
{"ts": "2026-07-17T15:15:55.719888+00:00", "type": "llm_call", "call_index": 54, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:15:41.492745+00:00", "finished_at": "2026-07-17T15:15:55.718888+00:00", "duration_s": 14.23399999999674, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:15:41.492745+00:00", "finished_at": "2026-07-17T15:15:55.718888+00:00", "duration_s": 14.23399999999674, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "165942", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:15:44 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301342-uNTyxknnETWDaC8aw4PG", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca341c0a9103dd-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301342-uNTyxknnETWDaC8aw4PG\",\"object\":\"chat.completion\",\"created\":1784301342,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":44303,\"completion_tokens\":564,\"total_tokens\":44867,\"cost\":0.00942650436,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":44224,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00942650436,\"upstream_inference_prompt_cost\":0.00776631396,\"upstream_inference_completions_cost\":0.0016601904},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxMzQyLXVOVHl4a25uRVRXRGFDOGF3NFBHIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTM0MiwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLTg4MDVhOTkyNDRiMGI5OTQiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbiMgTGV0IG1lIGNoZWNrIHRoZSBpbWFnZSBtb3JlIGNhcmVmdWxseSBieSBzYXZpbmcgYSBzbWFsbGVyIHZlcnNpb25cXG4jIGFuZCBleGFtaW5pbmcgY29sb3IgZGlzdHJpYnV0aW9uXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG4jIENvbG9yIGFuYWx5c2lzOiBjaGVjayBmb3IgcmVkLCBncmVlbiwgYW5kIG5ldXRyYWwgYXJlYXNcXG5yZWRfY291bnQgPSAwXFxuZ3JlZW5fY291bnQgPSAwXFxubmV1dHJhbF9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgIyBSZWQgZG9taW5hbnRcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgICMgR3JlZW4gZG9taW5hbnRcXG4gICAgZWxpZiBnID4gMC4xNSBhbmQgZyA+IHIgKiAxLjMgYW5kIGcgPiBiICogMS4zOlxcbiAgICAgICAgZ3JlZW5fY291bnQgKz0gMVxcbiAgICAjIFdhcm0gKHllbGxvdy9vcmFuZ2UpXFxuICAgIGVsaWYgciA+IDAuMiBhbmQgZyA+IDAuMTUgYW5kIHIgPiBiICogMS4zOlxcbiAgICAgICAgd2FybV9jb3VudCArPSAxXFxuICAgICMgTmV1dHJhbFxcbiAgICBlbGlmIGFicyhyIC0gZykgPCAwLjA1IGFuZCBhYnMoZyAtIGIpIDwgMC4wNTpcXG4gICAgICAgIG5ldXRyYWxfY291bnQgKz0gMVxcblxcbnByaW50KGZcXFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IHt0b3RhbH1cXFwiKVxcbnByaW50KGZcXFwiUmVkIGRvbWluYW50OiB7cmVkX2NvdW50fSAoezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIkdyZWVuIGRvbWluYW50OiB7Z3JlZW5fY291bnR9ICh7MTAwKmdyZWVuX2NvdW50L3RvdGFsOi4xZn0lKVxcXCIpXFxucHJpbnQoZlxcXCJXYXJtICh5ZWxsb3cvb3JhbmdlKToge3dhcm1fY291bnR9ICh7MTAwKndhcm1fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIk5ldXRyYWw6IHtuZXV0cmFsX2NvdW50fSAoezEwMCpuZXV0cmFsX2NvdW50L3RvdGFsOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0ZWFwb3QgaXMgdmlzaWJsZSAoYnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHMpXFxuYnJpZ2h0X21ldGFsbGljID0gMFxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIGlmIHIgPiAwLjcgYW5kIGcgPiAwLjY1IGFuZCBiID4gMC41NTpcXG4gICAgICAgIGJyaWdodF9tZXRhbGxpYyArPSAxXFxucHJpbnQoZlxcXCJcXFxcbkJyaWdodCBtZXRhbGxpYyBoaWdobGlnaHRzOiB7YnJpZ2h0X21ldGFsbGljfSAoezEwMCpicmlnaHRfbWV0YWxsaWMvdG90YWw6LjFmfSUpXFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6NDQzMDMsImNvbXBsZXRpb25fdG9rZW5zIjo1NjQsInRvdGFsX3Rva2VucyI6NDQ4NjcsImNvc3QiOjAuMDA5NDI2NTA0MzYsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6NDQyMjQsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA5NDI2NTA0MzYsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDc3NjYzMTM5NiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAxNjYwMTkwNH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Let me check the image more carefully by saving a smaller version\n# and examining color distribution\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview5.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Color analysis: check for red, green, and neutral areas\nred_count = 0\ngreen_count = 0\nneutral_count = 0\nwarm_count = 0\ntotal = 0\n\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    total += 1\n    brightness = (r + g + b) / 3\n    \n    if brightness < 0.05:\n        continue\n    \n    # Red dominant\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\n        red_count += 1\n    # Green dominant\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\n        green_count += 1\n    # Warm (yellow/orange)\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\n        warm_count += 1\n    # Neutral\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\n        neutral_count += 1\n\nprint(f\"Total visible pixels: {total}\")\nprint(f\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\")\nprint(f\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\")\nprint(f\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\")\nprint(f\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\")\n\n# Check if teapot is visible (bright metallic highlights)\nbright_metallic = 0\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    if r > 0.7 and g > 0.65 and b > 0.55:\n        bright_metallic += 1\nprint(f\"\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 44303, "tokens_out": 564, "cost_usd": 0.00942650436, "cached_tokens": 44224}, "error": null}
{"ts": "2026-07-17T15:15:55.724401+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Let me check the image more carefully by saving a smaller version\n# and examining color distribution\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview5.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Color analysis: check for red, green, and neutral areas\nred_count = 0\ngreen_count = 0\nneutral_count = 0\nwarm_count = 0\ntotal = 0\n\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    total += 1\n    brightness = (r + g + b) / 3\n    \n    if brightness < 0.05:\n        continue\n    \n    # Red dominant\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\n        red_count += 1\n    # Green dominant\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\n        green_count += 1\n    # Warm (yellow/orange)\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\n        warm_count += 1\n    # Neutral\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\n        neutral_count += 1\n\nprint(f\"Total visible pixels: {total}\")\nprint(f\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\")\nprint(f\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\")\nprint(f\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\")\nprint(f\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\")\n\n# Check if teapot is visible (bright metallic highlights)\nbright_metallic = 0\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    if r > 0.7 and g > 0.65 and b > 0.55:\n        bright_metallic += 1\nprint(f\"\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:15:55.724401+00:00", "type": "tool_call", "id": "chatcmpl-tool-8805a99244b0b994", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Let me check the image more carefully by saving a smaller version\n# and examining color distribution\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview5.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Color analysis: check for red, green, and neutral areas\nred_count = 0\ngreen_count = 0\nneutral_count = 0\nwarm_count = 0\ntotal = 0\n\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    total += 1\n    brightness = (r + g + b) / 3\n    \n    if brightness < 0.05:\n        continue\n    \n    # Red dominant\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\n        red_count += 1\n    # Green dominant\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\n        green_count += 1\n    # Warm (yellow/orange)\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\n        warm_count += 1\n    # Neutral\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\n        neutral_count += 1\n\nprint(f\"Total visible pixels: {total}\")\nprint(f\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\")\nprint(f\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\")\nprint(f\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\")\nprint(f\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\")\n\n# Check if teapot is visible (bright metallic highlights)\nbright_metallic = 0\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    if r > 0.7 and g > 0.65 and b > 0.55:\n        bright_metallic += 1\nprint(f\"\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:15:58.227076+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:16:15.658289+00:00", "type": "llm_call", "call_index": 55, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:15:58.228083+00:00", "finished_at": "2026-07-17T15:16:15.657291+00:00", "duration_s": 17.421000000002095, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:15:58.228083+00:00", "finished_at": "2026-07-17T15:16:15.657291+00:00", "duration_s": 17.421000000002095, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "168266", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:16:01 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301359-ZF1FhC8HJcjdesnYBNzg", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca3484aed5993a-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301359-ZF1FhC8HJcjdesnYBNzg\",\"object\":\"chat.completion\",\"created\":1784301359,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":44982,\"completion_tokens\":615,\"total_tokens\":45597,\"cost\":0.01016376912,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":44288,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.01016376912,\"upstream_inference_prompt_cost\":0.00835345512,\"upstream_inference_completions_cost\":0.001810314},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDEzNTktWkYxRmhDOEhKY2pkZXNuWUJOemciLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAxMzU5LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUg4oCUIHRoZSBncmVlbiBwYW5lbCBpc24ndCBzaG93aW5nIHVwIHdlbGwgYmVjYXVzZSBpdCdzIGJlaGluZCB0aGUgb2JqZWN0cy4gVGhlIHJlZCBjbG90aCBpcyBkb21pbmFudC4gTGV0IG1lIGFkanVzdCB0aGUgZ3JlZW4gcGFuZWwgdG8gYmUgbW9yZSB2aXNpYmxlIGFuZCBpbXByb3ZlIHRoZSBDb3JuZWxsIGJveCBwYWxldHRlIGJhbGFuY2UuIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLTgxYjBmNTA1MmI2YjQ5NzQiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgQ09STkVMTCBCT1ggUEFMRVRURSBCQUxBTkNFXFxuIyBUaGUgZ3JlZW4gbmVlZHMgdG8gYmUgbW9yZSB2aXNpYmxlIGZhY2luZyB0aGUgcmVkXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIE1ha2UgdGhlIGdyZWVuIHBhbmVsIGxhcmdlciBhbmQgbW9yZSBwcm9taW5lbnQgb24gdGhlIHJpZ2h0XFxuZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl1cXG5ncmVlbl9wYW5lbC5sb2NhdGlvbiA9ICgyLjUsIDEuNSwgMS44KVxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygyMCkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMy4wLCA0LjAsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgTWFrZSB0aGUgcmVkIHBhbmVsIGxhcmdlciB0b29cXG5yZWRfcGFuZWwgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJSZWRQYW5lbFxcXCJdXFxucmVkX3BhbmVsLmxvY2F0aW9uID0gKC0yLjUsIDEuNSwgMS44KVxcbnJlZF9wYW5lbC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoOTApLCAwLCBtYXRoLnJhZGlhbnMoLTIwKSlcXG5yZWRfcGFuZWwuc2NhbGUgPSAoMy4wLCA0LjAsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgQnJpZ2h0ZW4gdGhlIGdyZWVuIHBhbmVsIG1hdGVyaWFsIHNsaWdodGx5IHNvIGl0IHJlYWRzXFxubWF0X2dyZWVuX3BhbmVsID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuUGFuZWxcXFwiXVxcbm50ID0gbWF0X2dyZWVuX3BhbmVsLm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNiwgMC4yOCwgMC4wNywgMS4wKSAgIyBzbGlnaHRseSBicmlnaHRlciBncmVlblxcblxcbiMgQWxzbyBtYWtlIHRoZSByZWQgcGFuZWwgc2xpZ2h0bHkgYnJpZ2h0ZXJcXG5tYXRfcmVkX3BhbmVsID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFBhbmVsXFxcIl1cXG5udCA9IG1hdF9yZWRfcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQyLCAwLjA2LCAwLjA1LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIHJlZFxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gdmVsdmV0IGNsb3RoIGJyaWdodGVyIHRvb1xcbm1hdF9ncmVlbl92ZWx2ZXQgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5WZWx2ZXRcXFwiXVxcbm50ID0gbWF0X2dyZWVuX3ZlbHZldC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDcsIDAuMzUsIDAuMDgsIDEuMClcXG5cXG4jIFVwZGF0ZSB0aGUgY29sb3IgcmFtcCBpbiBncmVlbiB2ZWx2ZXRcXG5mb3Igbm9kZSBpbiBudC5ub2RlczpcXG4gICAgaWYgbm9kZS50eXBlID09ICdWQUxUT1JHQic6XFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNiwgMC4zMiwgMC4wNywgMS4wKVxcbiAgICAgICAgbm9kZS5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTAsIDAuNDAsIDAuMTAsIDEuMClcXG5cXG5wcmludChcXFwiQ29ybmVsbCBwYWxldHRlIGJhbGFuY2VkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjQ0OTgyLCJjb21wbGV0aW9uX3Rva2VucyI6NjE1LCJ0b3RhbF90b2tlbnMiOjQ1NTk3LCJjb3N0IjowLjAxMDE2Mzc2OTEyLCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjQ0Mjg4LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAxMDE2Mzc2OTEyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA4MzUzNDU1MTIsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMTgxMDMxNH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\n# ============================================================\n# IMPROVE CORNELL BOX PALETTE BALANCE\n# The green needs to be more visible facing the red\n# ============================================================\n\n# Make the green panel larger and more prominent on the right\ngreen_panel = bpy.data.objects[\"GreenPanel\"]\ngreen_panel.location = (2.5, 1.5, 1.8)\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\ngreen_panel.scale = (3.0, 4.0, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# Make the red panel larger too\nred_panel = bpy.data.objects[\"RedPanel\"]\nred_panel.location = (-2.5, 1.5, 1.8)\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\nred_panel.scale = (3.0, 4.0, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# Brighten the green panel material slightly so it reads\nmat_green_panel = bpy.data.materials[\"M_GreenPanel\"]\nnt = mat_green_panel.node_tree\nbsdf = nt.nodes['Principled BSDF']\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\n\n# Also make the red panel slightly brighter\nmat_red_panel = bpy.data.materials[\"M_RedPanel\"]\nnt = mat_red_panel.node_tree\nbsdf = nt.nodes['Principled BSDF']\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\n\n# Make the green velvet cloth brighter too\nmat_green_velvet = bpy.data.materials[\"M_GreenVelvet\"]\nnt = mat_green_velvet.node_tree\nbsdf = nt.nodes['Principled BSDF']\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\n\n# Update the color ramp in green velvet\nfor node in nt.nodes:\n    if node.type == 'VALTORGB':\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\n\nprint(\"Cornell palette balanced.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 44982, "tokens_out": 615, "cost_usd": 0.01016376912, "cached_tokens": 44288}, "error": null}
{"ts": "2026-07-17T15:16:15.663311+00:00", "type": "assistant", "text": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\n# ============================================================\n# IMPROVE CORNELL BOX PALETTE BALANCE\n# The green needs to be more visible facing the red\n# ============================================================\n\n# Make the green panel larger and more prominent on the right\ngreen_panel = bpy.data.objects[\"GreenPanel\"]\ngreen_panel.location = (2.5, 1.5, 1.8)\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\ngreen_panel.scale = (3.0, 4.0, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# Make the red panel larger too\nred_panel = bpy.data.objects[\"RedPanel\"]\nred_panel.location = (-2.5, 1.5, 1.8)\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\nred_panel.scale = (3.0, 4.0, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# Brighten the green panel material slightly so it reads\nmat_green_panel = bpy.data.materials[\"M_GreenPanel\"]\nnt = mat_green_panel.node_tree\nbsdf = nt.nodes['Principled BSDF']\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\n\n# Also make the red panel slightly brighter\nmat_red_panel = bpy.data.materials[\"M_RedPanel\"]\nnt = mat_red_panel.node_tree\nbsdf = nt.nodes['Principled BSDF']\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\n\n# Make the green velvet cloth brighter too\nmat_green_velvet = bpy.data.materials[\"M_GreenVelvet\"]\nnt = mat_green_velvet.node_tree\nbsdf = nt.nodes['Principled BSDF']\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\n\n# Update the color ramp in green velvet\nfor node in nt.nodes:\n    if node.type == 'VALTORGB':\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\n\nprint(\"Cornell palette balanced.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:16:15.663311+00:00", "type": "tool_call", "id": "chatcmpl-tool-81b0f5052b6b4974", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\n# ============================================================\n# IMPROVE CORNELL BOX PALETTE BALANCE\n# The green needs to be more visible facing the red\n# ============================================================\n\n# Make the green panel larger and more prominent on the right\ngreen_panel = bpy.data.objects[\"GreenPanel\"]\ngreen_panel.location = (2.5, 1.5, 1.8)\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\ngreen_panel.scale = (3.0, 4.0, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# Make the red panel larger too\nred_panel = bpy.data.objects[\"RedPanel\"]\nred_panel.location = (-2.5, 1.5, 1.8)\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\nred_panel.scale = (3.0, 4.0, 1)\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\n\n# Brighten the green panel material slightly so it reads\nmat_green_panel = bpy.data.materials[\"M_GreenPanel\"]\nnt = mat_green_panel.node_tree\nbsdf = nt.nodes['Principled BSDF']\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\n\n# Also make the red panel slightly brighter\nmat_red_panel = bpy.data.materials[\"M_RedPanel\"]\nnt = mat_red_panel.node_tree\nbsdf = nt.nodes['Principled BSDF']\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\n\n# Make the green velvet cloth brighter too\nmat_green_velvet = bpy.data.materials[\"M_GreenVelvet\"]\nnt = mat_green_velvet.node_tree\nbsdf = nt.nodes['Principled BSDF']\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\n\n# Update the color ramp in green velvet\nfor node in nt.nodes:\n    if node.type == 'VALTORGB':\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\n\nprint(\"Cornell palette balanced.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:16:16.505060+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:16:30.117223+00:00", "type": "llm_call", "call_index": 56, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:16:16.506067+00:00", "finished_at": "2026-07-17T15:16:30.117223+00:00", "duration_s": 13.60999999998603, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:16:16.506067+00:00", "finished_at": "2026-07-17T15:16:30.116218+00:00", "duration_s": 13.60999999998603, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "170888", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:16:20 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301377-EiRqB5n7o9OCTpT4lgMs", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca34f9e8a6f76d-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301377-EiRqB5n7o9OCTpT4lgMs\",\"object\":\"chat.completion\",\"created\":1784301377,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":45636,\"completion_tokens\":503,\"total_tokens\":46139,\"cost\":0.00995851992,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":44928,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00995851992,\"upstream_inference_prompt_cost\":0.00847788912,\"upstream_inference_completions_cost\":0.0014806308},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxMzc3LUVpUnFCNW43bzlPQ1RwVDRsZ01zIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTM3NywibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLWE0YjdjOTE1ZjJkZWViMmIiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbiMgUXVpY2sgcmVuZGVyIHRvIGNoZWNrIGNvbG9yIGJhbGFuY2VcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAyNFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc2LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG4jIENvbG9yIGFuYWx5c2lzXFxucmVkX2NvdW50ID0gMFxcbmdyZWVuX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgZWxpZiBnID4gMC4xMiBhbmQgZyA+IHIgKiAxLjIgYW5kIGcgPiBiICogMS4zOlxcbiAgICAgICAgZ3JlZW5fY291bnQgKz0gMVxcbiAgICBlbGlmIHIgPiAwLjIgYW5kIGcgPiAwLjE1IGFuZCByID4gYiAqIDEuMzpcXG4gICAgICAgIHdhcm1fY291bnQgKz0gMVxcblxcbnByaW50KGZcXFwiUmVkIGRvbWluYW50OiB7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JVxcXCIpXFxucHJpbnQoZlxcXCJHcmVlbiBkb21pbmFudDogezEwMCpncmVlbl9jb3VudC90b3RhbDouMWZ9JVxcXCIpXFxucHJpbnQoZlxcXCJXYXJtOiB7MTAwKndhcm1fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcblxcbiMgQ2hlY2sgcmlnaHQgc2lkZSBzcGVjaWZpY2FsbHkgZm9yIGdyZWVuXFxucmlnaHRfZ3JlZW4gPSAwXFxucmlnaHRfdG90YWwgPSAwXFxuZm9yIHkgaW4gcmFuZ2UoaCk6XFxuICAgIGZvciB4IGluIHJhbmdlKHcgKiAyIC8vIDMsIHcpOlxcbiAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgciwgZywgYiA9IHBpeGVsc1tpZHhdLCBwaXhlbHNbaWR4KzFdLCBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgcmlnaHRfdG90YWwgKz0gMVxcbiAgICAgICAgICAgIGlmIGcgPiAwLjEgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMjpcXG4gICAgICAgICAgICAgICAgcmlnaHRfZ3JlZW4gKz0gMVxcbnByaW50KGZcXFwiUmlnaHQgc2lkZSBncmVlbjogezEwMCpyaWdodF9ncmVlbi9yaWdodF90b3RhbDouMWZ9JVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjQ1NjM2LCJjb21wbGV0aW9uX3Rva2VucyI6NTAzLCJ0b3RhbF90b2tlbnMiOjQ2MTM5LCJjb3N0IjowLjAwOTk1ODUxOTkyLCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjQ0OTI4LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwOTk1ODUxOTkyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA4NDc3ODg5MTIsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMTQ4MDYzMDh9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Quick render to check color balance\nscene = bpy.context.scene\nscene.cycles.samples = 24\nscene.render.filepath = \"C:/tmp/still_life_preview6.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview6.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Color analysis\nred_count = 0\ngreen_count = 0\nwarm_count = 0\ntotal = 0\n\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    total += 1\n    brightness = (r + g + b) / 3\n    \n    if brightness < 0.05:\n        continue\n    \n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\n        red_count += 1\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\n        green_count += 1\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\n        warm_count += 1\n\nprint(f\"Red dominant: {100*red_count/total:.1f}%\")\nprint(f\"Green dominant: {100*green_count/total:.1f}%\")\nprint(f\"Warm: {100*warm_count/total:.1f}%\")\n\n# Check right side specifically for green\nright_green = 0\nright_total = 0\nfor y in range(h):\n    for x in range(w * 2 // 3, w):\n        idx = (y * w + x) * 4\n        if idx + 2 < len(pixels):\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\n            right_total += 1\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\n                right_green += 1\nprint(f\"Right side green: {100*right_green/right_total:.1f}%\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 45636, "tokens_out": 503, "cost_usd": 0.00995851992, "cached_tokens": 44928}, "error": null}
{"ts": "2026-07-17T15:16:30.122501+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Quick render to check color balance\nscene = bpy.context.scene\nscene.cycles.samples = 24\nscene.render.filepath = \"C:/tmp/still_life_preview6.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview6.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Color analysis\nred_count = 0\ngreen_count = 0\nwarm_count = 0\ntotal = 0\n\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    total += 1\n    brightness = (r + g + b) / 3\n    \n    if brightness < 0.05:\n        continue\n    \n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\n        red_count += 1\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\n        green_count += 1\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\n        warm_count += 1\n\nprint(f\"Red dominant: {100*red_count/total:.1f}%\")\nprint(f\"Green dominant: {100*green_count/total:.1f}%\")\nprint(f\"Warm: {100*warm_count/total:.1f}%\")\n\n# Check right side specifically for green\nright_green = 0\nright_total = 0\nfor y in range(h):\n    for x in range(w * 2 // 3, w):\n        idx = (y * w + x) * 4\n        if idx + 2 < len(pixels):\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\n            right_total += 1\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\n                right_green += 1\nprint(f\"Right side green: {100*right_green/right_total:.1f}%\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:16:30.122501+00:00", "type": "tool_call", "id": "chatcmpl-tool-a4b7c915f2deeb2b", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Quick render to check color balance\nscene = bpy.context.scene\nscene.cycles.samples = 24\nscene.render.filepath = \"C:/tmp/still_life_preview6.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview6.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Color analysis\nred_count = 0\ngreen_count = 0\nwarm_count = 0\ntotal = 0\n\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    total += 1\n    brightness = (r + g + b) / 3\n    \n    if brightness < 0.05:\n        continue\n    \n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\n        red_count += 1\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\n        green_count += 1\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\n        warm_count += 1\n\nprint(f\"Red dominant: {100*red_count/total:.1f}%\")\nprint(f\"Green dominant: {100*green_count/total:.1f}%\")\nprint(f\"Warm: {100*warm_count/total:.1f}%\")\n\n# Check right side specifically for green\nright_green = 0\nright_total = 0\nfor y in range(h):\n    for x in range(w * 2 // 3, w):\n        idx = (y * w + x) * 4\n        if idx + 2 < len(pixels):\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\n            right_total += 1\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\n                right_green += 1\nprint(f\"Right side green: {100*right_green/right_total:.1f}%\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:16:55.252432+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:16:58.531453+00:00", "type": "llm_call", "call_index": 57, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:16:55.254442+00:00", "finished_at": "2026-07-17T15:16:58.531453+00:00", "duration_s": 3.2809999999881256, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:16:55.254442+00:00", "finished_at": "2026-07-17T15:16:58.530447+00:00", "duration_s": 3.2809999999881256, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "172893", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:16:58 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301416-uD59aUXcaDgUjCd7yFsF", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca35e909f1f4ac-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301416-uD59aUXcaDgUjCd7yFsF\",\"object\":\"chat.completion\",\"created\":1784301416,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":46208,\"completion_tokens\":22,\"total_tokens\":46230,\"cost\":0.00854147088,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":45632,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00854147088,\"upstream_inference_prompt_cost\":0.00847671168,\"upstream_inference_completions_cost\":0.0000647592},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxNDE2LXVENTlhVVhjYURnVWpDZDd5RnNGIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTQxNiwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0NjIwOCwiY29tcGxldGlvbl90b2tlbnMiOjIyLCJ0b3RhbF90b2tlbnMiOjQ2MjMwLCJjb3N0IjowLjAwODU0MTQ3MDg4LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjQ1NjMyLCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwODU0MTQ3MDg4LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA4NDc2NzExNjgsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMDA2NDc1OTJ9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}], "tokens_in": 46208, "tokens_out": 22, "cost_usd": 0.00854147088, "cached_tokens": 45632}, "error": null}
{"ts": "2026-07-17T15:16:58.537022+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:16:58.537022+00:00", "type": "tool_call", "id": "chatcmpl-tool-9f686bd02109d814", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}
{"ts": "2026-07-17T15:16:58.973595+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "name": "get_screenshot_of_area_as_image", "text": "", "is_error": false, "has_image": true, "image_b64": "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"}
{"ts": "2026-07-17T15:17:30.529258+00:00", "type": "llm_call", "call_index": 58, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:16:58.977100+00:00", "finished_at": "2026-07-17T15:17:30.529258+00:00", "duration_s": 31.562000000005355, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:16:58.977100+00:00", "finished_at": "2026-07-17T15:17:30.528259+00:00", "duration_s": 31.562000000005355, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "173179", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:17:01 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301419-WQJcziNhhsjkruSxUZV2", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca36004cd8e882-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301419-WQJcziNhhsjkruSxUZV2\",\"object\":\"chat.completion\",\"created\":1784301419,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":46234,\"completion_tokens\":1283,\"total_tokens\":47517,\"cost\":0.01183840992,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":46208,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.01183840992,\"upstream_inference_prompt_cost\":0.00806177112,\"upstream_inference_completions_cost\":0.0037766388},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTQxOS1XUUpjemlOaGhzamtydVN4VVpWMiIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDE0MTksIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgZ3JlZW4gaXMgbm93IHZpc2libGUuIExldCBtZSBpbXByb3ZlIHRoZSBjaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIHRvIGJlIG1vcmUgcHJvcGVybHkgcmVmbGVjdGl2ZSAocmF5LXRyYWNpbmcgZGVtbyBjbGFzc2ljKSwgYW5kIGFkZCBhIGZldyBtb3JlIHJlZmluZW1lbnRzLiBMZXQgbWUgYWxzbyBtYWtlIHRoZSBTdXphbm5lIGJ1c3QgbG9vayBtb3JlIGxpa2UgYSBwcm9wZXIgYnVzdC4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDSEVDS0VSRUQgU1BIRVJFOiBUcnVlIHJheS10cmFjaW5nIHJlZmxlY3RpdmUgY2hyb21lXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX0NoZWNrZXJlZFNwaGVyZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDEwMDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg2MDAsIDApKVxcblxcbiMgUGVyZmVjdCBtaXJyb3IgY2hyb21lIHdpdGggY2hlY2tlciBwYXR0ZXJuXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4wMiAgIyB2ZXJ5IHBvbGlzaGVkLCBjYXRjaGVzIHJlZmxlY3Rpb25zXFxuXFxuIyBDaGVja2VyIHBhdHRlcm4gdXNpbmcgdGV4dHVyZSBjb29yZGluYXRlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTQwMCwgMCkpXFxubWFwcGluZyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1hcHBpbmcnLCAoLTIwMCwgMCkpXFxubWFwcGluZy5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9ICgzLjAsIDMuMCwgMy4wKVxcbm50LmxpbmtzLm5ldyh0ZXhfY29vcmQub3V0cHV0c1snR2VuZXJhdGVkJ10sIG1hcHBpbmcuaW5wdXRzWydWZWN0b3InXSlcXG5cXG5jaGVja2VyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q2hlY2tlcicsICgwLCAwKSlcXG5jaGVja2VyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubnQubGlua3MubmV3KG1hcHBpbmcub3V0cHV0c1snVmVjdG9yJ10sIGNoZWNrZXIuaW5wdXRzWydWZWN0b3InXSlcXG5cXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMjAwLCAwKSlcXG5udC5saW5rcy5uZXcoY2hlY2tlci5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjAyLCAwLjAyLCAwLjAyLCAxLjApICAjIGRhcmsgc3F1YXJlc1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjk1LCAwLjk1LCAwLjk1LCAxLjApICAjIGxpZ2h0IHNxdWFyZXNcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIFNVWkFOTkU6IEJldHRlciBtYXJibGUgd2l0aCBzdWJzdXJmYWNlIHNjYXR0ZXJpbmcgZmVlbFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoODAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoNDAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44OCwgMC44NSwgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yNVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBNYXJibGUgdmVpbmluZyB1c2luZyBub2lzZSBhbmQgd2F2ZVxcbnRleF9jb29yZCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleENvb3JkJywgKC02MDAsIDEwMCkpXFxubWFwcGluZyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1hcHBpbmcnLCAoLTQwMCwgMTAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDEuMCwgMy4wLCAxLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgMjAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm5vaXNlLmlucHV0c1snRGlzdG9ydGlvbiddLmRlZmF1bHRfdmFsdWUgPSAyLjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgbm9pc2UuaW5wdXRzWydWZWN0b3InXSlcXG5cXG53YXZlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4V2F2ZScsICgtMjAwLCAxMDApKVxcbndhdmUuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAzLjBcXG53YXZlLmlucHV0c1snRGlzdG9ydGlvbiddLmRlZmF1bHRfdmFsdWUgPSAzLjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgd2F2ZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzZdKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzddKVxcbm50LmxpbmtzLm5ldyhtaXgub3V0cHV0c1syXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG4jIENvbG9yIHJhbXAgZm9yIHZlaW5pbmdcXG5yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMjAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhtaXgub3V0cHV0c1syXSwgcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbnJhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc1LCAxLjApXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNDUsIDAuMzgsIDAuMzAsIDEuMClcXG5udC5saW5rcy5uZXcocmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgyMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjA4XFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgLTEwMCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTAwLjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snQmFzZSBDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlN1emFubmUgbWFyYmxlIG1hdGVyaWFsIGltcHJvdmVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjQ2MjM0LCJjb21wbGV0aW9uX3Rva2VucyI6MTI4MywidG90YWxfdG9rZW5zIjo0NzUxNywiY29zdCI6MC4wMTE4Mzg0MDk5MiwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjo0NjIwOCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMTE4Mzg0MDk5MiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwODA2MTc3MTEyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDM3NzY2Mzg4fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\n# ============================================================\nmat = bpy.data.materials.get(\"M_CheckeredSphere\")\nnt = mat.node_tree\nfor n in list(nt.nodes):\n    nt.nodes.remove(n)\n\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\n\n# Perfect mirror chrome with checker pattern\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\n\n# Checker pattern using texture coordinate\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\n\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\nchecker.inputs['Scale'].default_value = 8.0\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\n\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nprint(\"Checkered sphere material improved - true reflective chrome.\")\n\n# ============================================================\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\n# ============================================================\nmat = bpy.data.materials.get(\"M_SuzanneMarble\")\nnt = mat.node_tree\nfor n in list(nt.nodes):\n    nt.nodes.remove(n)\n\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\nbsdf.inputs['Roughness'].default_value = 0.25\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n\n# Marble veining using noise and wave\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\nnoise.inputs['Scale'].default_value = 3.0\nnoise.inputs['Detail'].default_value = 3.0\nnoise.inputs['Distortion'].default_value = 2.0\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\n\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\nwave.inputs['Scale'].default_value = 3.0\nwave.inputs['Distortion'].default_value = 3.0\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\n\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\nmix.data_type = 'RGBA'\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\n\n# Color ramp for veining\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Subtle bump\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\nbump.inputs['Strength'].default_value = 0.08\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\nnoise3.inputs['Scale'].default_value = 100.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nprint(\"Suzanne marble material improved.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 46234, "tokens_out": 1283, "cost_usd": 0.01183840992, "cached_tokens": 46208}, "error": null}
{"ts": "2026-07-17T15:17:30.535284+00:00", "type": "assistant", "text": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\n# ============================================================\nmat = bpy.data.materials.get(\"M_CheckeredSphere\")\nnt = mat.node_tree\nfor n in list(nt.nodes):\n    nt.nodes.remove(n)\n\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\n\n# Perfect mirror chrome with checker pattern\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\n\n# Checker pattern using texture coordinate\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\n\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\nchecker.inputs['Scale'].default_value = 8.0\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\n\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nprint(\"Checkered sphere material improved - true reflective chrome.\")\n\n# ============================================================\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\n# ============================================================\nmat = bpy.data.materials.get(\"M_SuzanneMarble\")\nnt = mat.node_tree\nfor n in list(nt.nodes):\n    nt.nodes.remove(n)\n\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\nbsdf.inputs['Roughness'].default_value = 0.25\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n\n# Marble veining using noise and wave\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\nnoise.inputs['Scale'].default_value = 3.0\nnoise.inputs['Detail'].default_value = 3.0\nnoise.inputs['Distortion'].default_value = 2.0\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\n\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\nwave.inputs['Scale'].default_value = 3.0\nwave.inputs['Distortion'].default_value = 3.0\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\n\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\nmix.data_type = 'RGBA'\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\n\n# Color ramp for veining\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Subtle bump\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\nbump.inputs['Strength'].default_value = 0.08\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\nnoise3.inputs['Scale'].default_value = 100.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nprint(\"Suzanne marble material improved.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:17:30.535284+00:00", "type": "tool_call", "id": "chatcmpl-tool-ad7552f450a30efc", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# ============================================================\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\n# ============================================================\nmat = bpy.data.materials.get(\"M_CheckeredSphere\")\nnt = mat.node_tree\nfor n in list(nt.nodes):\n    nt.nodes.remove(n)\n\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\n\n# Perfect mirror chrome with checker pattern\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\n\n# Checker pattern using texture coordinate\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\n\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\nchecker.inputs['Scale'].default_value = 8.0\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\n\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nprint(\"Checkered sphere material improved - true reflective chrome.\")\n\n# ============================================================\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\n# ============================================================\nmat = bpy.data.materials.get(\"M_SuzanneMarble\")\nnt = mat.node_tree\nfor n in list(nt.nodes):\n    nt.nodes.remove(n)\n\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\nbsdf.inputs['Roughness'].default_value = 0.25\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\n\n# Marble veining using noise and wave\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\n\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\nnoise.inputs['Scale'].default_value = 3.0\nnoise.inputs['Detail'].default_value = 3.0\nnoise.inputs['Distortion'].default_value = 2.0\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\n\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\nwave.inputs['Scale'].default_value = 3.0\nwave.inputs['Distortion'].default_value = 3.0\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\n\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\nmix.data_type = 'RGBA'\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\n\n# Color ramp for veining\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\n# Subtle bump\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\nbump.inputs['Strength'].default_value = 0.08\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\nnoise3.inputs['Scale'].default_value = 100.0\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nprint(\"Suzanne marble material improved.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:17:32.175428+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "name": "execute_blender_code", "text": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:17:40.461779+00:00", "type": "llm_call", "call_index": 59, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:17:32.176434+00:00", "finished_at": "2026-07-17T15:17:40.461779+00:00", "duration_s": 8.280999999988126, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:17:32.176434+00:00", "finished_at": "2026-07-17T15:17:40.460273+00:00", "duration_s": 8.280999999988126, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "178757", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:17:36 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301453-TIfYYTbpuq9ojdmjdKYj", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca36d23d8acbe3-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301453-TIfYYTbpuq9ojdmjdKYj\",\"object\":\"chat.completion\",\"created\":1784301453,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":47667,\"completion_tokens\":192,\"total_tokens\":47859,\"cost\":0.00996909012,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":46208,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00996909012,\"upstream_inference_prompt_cost\":0.00940391892,\"upstream_inference_completions_cost\":0.0005651712},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTQ1My1USWZZWVRicHVxOW9qZG1qZEtZaiIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDE0NTMsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0NzY2NywiY29tcGxldGlvbl90b2tlbnMiOjE5MiwidG90YWxfdG9rZW5zIjo0Nzg1OSwiY29zdCI6MC4wMDk5NjkwOTAxMiwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjo0NjIwOCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDk5NjkwOTAxMiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwOTQwMzkxODkyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDA1NjUxNzEyfSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\nmat = bpy.data.materials.get(\"M_SuzanneMarble\")\nnt = mat.node_tree\n\n# Remove the bad link\nfor link in list(nt.links):\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\n        nt.links.remove(link)\n        print(f\"Removed bad link from {link.from_node.name}\")\n\n# Verify the material works\nprint(\"Suzanne material nodes:\")\nfor node in nt.nodes:\n    print(f\"  {node.name} ({node.type})\")\n    \nprint(\"\\nLinks:\")\nfor link in nt.links:\n    print(f\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 47667, "tokens_out": 192, "cost_usd": 0.00996909012, "cached_tokens": 46208}, "error": null}
{"ts": "2026-07-17T15:17:40.465876+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\nmat = bpy.data.materials.get(\"M_SuzanneMarble\")\nnt = mat.node_tree\n\n# Remove the bad link\nfor link in list(nt.links):\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\n        nt.links.remove(link)\n        print(f\"Removed bad link from {link.from_node.name}\")\n\n# Verify the material works\nprint(\"Suzanne material nodes:\")\nfor node in nt.nodes:\n    print(f\"  {node.name} ({node.type})\")\n    \nprint(\"\\nLinks:\")\nfor link in nt.links:\n    print(f\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:17:40.465876+00:00", "type": "tool_call", "id": "chatcmpl-tool-88fb07aca4529ea6", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\nmat = bpy.data.materials.get(\"M_SuzanneMarble\")\nnt = mat.node_tree\n\n# Remove the bad link\nfor link in list(nt.links):\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\n        nt.links.remove(link)\n        print(f\"Removed bad link from {link.from_node.name}\")\n\n# Verify the material works\nprint(\"Suzanne material nodes:\")\nfor node in nt.nodes:\n    print(f\"  {node.name} ({node.type})\")\n    \nprint(\"\\nLinks:\")\nfor link in nt.links:\n    print(f\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:17:41.475581+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:17:49.395048+00:00", "type": "llm_call", "call_index": 60, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:17:41.475581+00:00", "finished_at": "2026-07-17T15:17:49.395048+00:00", "duration_s": 7.921999999991385, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:17:41.475581+00:00", "finished_at": "2026-07-17T15:17:49.393538+00:00", "duration_s": 7.921999999991385, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "180537", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:17:44 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301462-H4oJFJxeMDlF5Rw0FHQz", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca3709e90ff770-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301462-H4oJFJxeMDlF5Rw0FHQz\",\"object\":\"chat.completion\",\"created\":1784301462,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":48066,\"completion_tokens\":239,\"total_tokens\":48305,\"cost\":0.00940731744,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":47616,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00940731744,\"upstream_inference_prompt_cost\":0.00870379704,\"upstream_inference_completions_cost\":0.0007035204},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxNDYyLUg0b0pGSnhlTURsRjVSdzBGSFF6Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTQ2MiwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLTljZGRjZWQxNThhMTZhN2YiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbiMgQ29ubmVjdCBidW1wIHRvIEJTREYgTm9ybWFsIGFuZCBCU0RGIHRvIG91dHB1dFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBNYWtlIHN1cmUgYnVtcCBub3JtYWwgZ29lcyB0byBCU0RGXFxuYnVtcCA9IE5vbmVcXG5ic2RmID0gTm9uZVxcbm91dHB1dCA9IE5vbmVcXG5mb3Igbm9kZSBpbiBudC5ub2RlczpcXG4gICAgaWYgbm9kZS50eXBlID09ICdCVU1QJzpcXG4gICAgICAgIGJ1bXAgPSBub2RlXFxuICAgIGVsaWYgbm9kZS50eXBlID09ICdCU0RGX1BSSU5DSVBMRUQnOlxcbiAgICAgICAgYnNkZiA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ09VVFBVVF9NQVRFUklBTCc6XFxuICAgICAgICBvdXRwdXQgPSBub2RlXFxuXFxuaWYgYnVtcCBhbmQgYnNkZjpcXG4gICAgbnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4gICAgcHJpbnQoXFxcIkNvbm5lY3RlZCBidW1wIHRvIEJTREYgTm9ybWFsXFxcIilcXG5cXG5pZiBic2RmIGFuZCBvdXRwdXQ6XFxuICAgIG50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIEJTREYgdG8gb3V0cHV0XFxcIilcXG5cXG5wcmludChcXFwiXFxcXG5GaW5hbCBsaW5rczpcXFwiKVxcbmZvciBsaW5rIGluIG50LmxpbmtzOlxcbiAgICBwcmludChmXFxcIiAge2xpbmsuZnJvbV9ub2RlLm5hbWV9LntsaW5rLmZyb21fc29ja2V0Lm5hbWV9IC0+IHtsaW5rLnRvX25vZGUubmFtZX0ue2xpbmsudG9fc29ja2V0Lm5hbWV9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6NDgwNjYsImNvbXBsZXRpb25fdG9rZW5zIjoyMzksInRvdGFsX3Rva2VucyI6NDgzMDUsImNvc3QiOjAuMDA5NDA3MzE3NDQsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6NDc2MTYsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA5NDA3MzE3NDQsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDg3MDM3OTcwNCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAwNzAzNTIwNH0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Connect bump to BSDF Normal and BSDF to output\nmat = bpy.data.materials.get(\"M_SuzanneMarble\")\nnt = mat.node_tree\n\n# Make sure bump normal goes to BSDF\nbump = None\nbsdf = None\noutput = None\nfor node in nt.nodes:\n    if node.type == 'BUMP':\n        bump = node\n    elif node.type == 'BSDF_PRINCIPLED':\n        bsdf = node\n    elif node.type == 'OUTPUT_MATERIAL':\n        output = node\n\nif bump and bsdf:\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n    print(\"Connected bump to BSDF Normal\")\n\nif bsdf and output:\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n    print(\"Connected BSDF to output\")\n\nprint(\"\\nFinal links:\")\nfor link in nt.links:\n    print(f\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 48066, "tokens_out": 239, "cost_usd": 0.00940731744, "cached_tokens": 47616}, "error": null}
{"ts": "2026-07-17T15:17:49.399113+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Connect bump to BSDF Normal and BSDF to output\nmat = bpy.data.materials.get(\"M_SuzanneMarble\")\nnt = mat.node_tree\n\n# Make sure bump normal goes to BSDF\nbump = None\nbsdf = None\noutput = None\nfor node in nt.nodes:\n    if node.type == 'BUMP':\n        bump = node\n    elif node.type == 'BSDF_PRINCIPLED':\n        bsdf = node\n    elif node.type == 'OUTPUT_MATERIAL':\n        output = node\n\nif bump and bsdf:\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n    print(\"Connected bump to BSDF Normal\")\n\nif bsdf and output:\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n    print(\"Connected BSDF to output\")\n\nprint(\"\\nFinal links:\")\nfor link in nt.links:\n    print(f\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:17:49.399113+00:00", "type": "tool_call", "id": "chatcmpl-tool-9cddced158a16a7f", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Connect bump to BSDF Normal and BSDF to output\nmat = bpy.data.materials.get(\"M_SuzanneMarble\")\nnt = mat.node_tree\n\n# Make sure bump normal goes to BSDF\nbump = None\nbsdf = None\noutput = None\nfor node in nt.nodes:\n    if node.type == 'BUMP':\n        bump = node\n    elif node.type == 'BSDF_PRINCIPLED':\n        bsdf = node\n    elif node.type == 'OUTPUT_MATERIAL':\n        output = node\n\nif bump and bsdf:\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\n    print(\"Connected bump to BSDF Normal\")\n\nif bsdf and output:\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n    print(\"Connected BSDF to output\")\n\nprint(\"\\nFinal links:\")\nfor link in nt.links:\n    print(f\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:17:49.655116+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:18:01.610008+00:00", "type": "llm_call", "call_index": 61, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:17:49.656122+00:00", "finished_at": "2026-07-17T15:18:01.610008+00:00", "duration_s": 11.953999999997905, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:17:49.656122+00:00", "finished_at": "2026-07-17T15:18:01.610008+00:00", "duration_s": 11.953999999997905, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "182333", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9cddced158a16a7f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Connected bump to BSDF Normal\\\\nConnected BSDF to output\\\\n\\\\nFinal links:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n  Bump.Normal -> Principled BSDF.Normal\\\\n  Principled BSDF.BSDF -> Material Output.Surface\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWNkZGNlZDE1OGExNmE3ZiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBDb25uZWN0IGJ1bXAgdG8gQlNERiBOb3JtYWwgYW5kIEJTREYgdG8gb3V0cHV0XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5cXG4jIE1ha2Ugc3VyZSBidW1wIG5vcm1hbCBnb2VzIHRvIEJTREZcXG5idW1wID0gTm9uZVxcbmJzZGYgPSBOb25lXFxub3V0cHV0ID0gTm9uZVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ0JVTVAnOlxcbiAgICAgICAgYnVtcCA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ0JTREZfUFJJTkNJUExFRCc6XFxuICAgICAgICBic2RmID0gbm9kZVxcbiAgICBlbGlmIG5vZGUudHlwZSA9PSAnT1VUUFVUX01BVEVSSUFMJzpcXG4gICAgICAgIG91dHB1dCA9IG5vZGVcXG5cXG5pZiBidW1wIGFuZCBic2RmOlxcbiAgICBudC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXFwiKVxcblxcbmlmIGJzZGYgYW5kIG91dHB1dDpcXG4gICAgbnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuICAgIHByaW50KFxcXCJDb25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXFwiKVxcblxcbnByaW50KFxcXCJcXFxcbkZpbmFsIGxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05Y2RkY2VkMTU4YTE2YTdmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXG5Db25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXG5cXG5GaW5hbCBsaW5rczpcXG4gIFRleHR1cmUgQ29vcmRpbmF0ZS5HZW5lcmF0ZWQgLT4gTWFwcGluZy5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IE5vaXNlIFRleHR1cmUuVmVjdG9yXFxuICBNYXBwaW5nLlZlY3RvciAtPiBXYXZlIFRleHR1cmUuVmVjdG9yXFxuICBXYXZlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkFcXG4gIE5vaXNlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkJcXG4gIE1peC5SZXN1bHQgLT4gQ29sb3IgUmFtcC5GYWN0b3JcXG4gIENvbG9yIFJhbXAuQ29sb3IgLT4gUHJpbmNpcGxlZCBCU0RGLkJhc2UgQ29sb3JcXG4gIE5vaXNlIFRleHR1cmUuMDAxLkZhY3RvciAtPiBCdW1wLkhlaWdodFxcbiAgQnVtcC5Ob3JtYWwgLT4gUHJpbmNpcGxlZCBCU0RGLk5vcm1hbFxcbiAgUHJpbmNpcGxlZCBCU0RGLkJTREYgLT4gTWF0ZXJpYWwgT3V0cHV0LlN1cmZhY2VcXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:17:52 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301470-HOP2KygVepAKxP5rkA3c", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca373dff8c0389-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301470-HOP2KygVepAKxP5rkA3c\",\"object\":\"chat.completion\",\"created\":1784301470,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Good, Suzanne material is fixed. Now let me render to check everything looks good.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-a1bde82900051568\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":48453,\"completion_tokens\":436,\"total_tokens\":48889,\"cost\":0.01000799916,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":48064,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.01000799916,\"upstream_inference_prompt_cost\":0.00872458956,\"upstream_inference_completions_cost\":0.0012834096},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxNDcwLUhPUDJLeWdWZXBBS3hQNXJrQTNjIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTQ3MCwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ikdvb2QsIFN1emFubmUgbWF0ZXJpYWwgaXMgZml4ZWQuIE5vdyBsZXQgbWUgcmVuZGVyIHRvIGNoZWNrIGV2ZXJ5dGhpbmcgbG9va3MgZ29vZC4iLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYTFiZGU4MjkwMDA1MTU2OCIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMzJcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ny5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxucHJpbnQoXFxcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSgxMCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSgxMCk6XFxuICAgICAgICB4MSA9IGd4ICogdyAvLyAxMFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDEwXFxuICAgICAgICB5MSA9IGd5ICogaCAvLyAxMFxcbiAgICAgICAgeTIgPSAoZ3krMSkgKiBoIC8vIDEwXFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDI1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDI1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDY6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTI6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI6IHJvdyArPSBcXFwi4oCiIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4zOiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU6IHJvdyArPSBcXFwi4paTIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC42NTogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0ODQ1MywiY29tcGxldGlvbl90b2tlbnMiOjQzNiwidG90YWxfdG9rZW5zIjo0ODg4OSwiY29zdCI6MC4wMTAwMDc5OTkxNiwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjo0ODA2NCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMTAwMDc5OTkxNiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwODcyNDU4OTU2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDEyODM0MDk2fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview7.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview7.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (10x10 grid):\")\nfor gy in range(10):\n    row = \"\"\n    for gx in range(10):\n        x1 = gx * w // 10\n        x2 = (gx+1) * w // 10\n        y1 = gy * h // 10\n        y2 = (gy+1) * h // 10\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 25):\n            for x in range(x1, x2, 25):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.5: row += \"▓ \"\n        elif bright < 0.65: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 48453, "tokens_out": 436, "cost_usd": 0.01000799916, "cached_tokens": 48064}, "error": null}
{"ts": "2026-07-17T15:18:01.614571+00:00", "type": "assistant", "text": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview7.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview7.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (10x10 grid):\")\nfor gy in range(10):\n    row = \"\"\n    for gx in range(10):\n        x1 = gx * w // 10\n        x2 = (gx+1) * w // 10\n        y1 = gy * h // 10\n        y2 = (gy+1) * h // 10\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 25):\n            for x in range(x1, x2, 25):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.5: row += \"▓ \"\n        elif bright < 0.65: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:18:01.614571+00:00", "type": "tool_call", "id": "chatcmpl-tool-a1bde82900051568", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview7.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview7.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (10x10 grid):\")\nfor gy in range(10):\n    row = \"\"\n    for gx in range(10):\n        x1 = gx * w // 10\n        x2 = (gx+1) * w // 10\n        y1 = gy * h // 10\n        y2 = (gy+1) * h // 10\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 25):\n            for x in range(x1, x2, 25):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.5: row += \"▓ \"\n        elif bright < 0.65: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:18:30.739230+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-a1bde82900051568", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▒ ● ·             |\\n  Row 4: |█ ▒ ● ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:18:33.994748+00:00", "type": "llm_call", "call_index": 62, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:18:30.739960+00:00", "finished_at": "2026-07-17T15:18:33.993743+00:00", "duration_s": 3.26500000001397, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}"}, {"role": "assistant", "content": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a1bde82900051568", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▒ ● ·             |\\n  Row 4: |█ ▒ ● ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:18:30.739960+00:00", "finished_at": "2026-07-17T15:18:33.992228+00:00", "duration_s": 3.25, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "184666", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9cddced158a16a7f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Connected bump to BSDF Normal\\\\nConnected BSDF to output\\\\n\\\\nFinal links:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n  Bump.Normal -> Principled BSDF.Normal\\\\n  Principled BSDF.BSDF -> Material Output.Surface\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good, Suzanne material is fixed. Now let me render to check everything looks good.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a1bde82900051568\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a1bde82900051568\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▒ ● ·             |\\\\n  Row 4: |█ ▒ ● ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWNkZGNlZDE1OGExNmE3ZiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBDb25uZWN0IGJ1bXAgdG8gQlNERiBOb3JtYWwgYW5kIEJTREYgdG8gb3V0cHV0XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5cXG4jIE1ha2Ugc3VyZSBidW1wIG5vcm1hbCBnb2VzIHRvIEJTREZcXG5idW1wID0gTm9uZVxcbmJzZGYgPSBOb25lXFxub3V0cHV0ID0gTm9uZVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ0JVTVAnOlxcbiAgICAgICAgYnVtcCA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ0JTREZfUFJJTkNJUExFRCc6XFxuICAgICAgICBic2RmID0gbm9kZVxcbiAgICBlbGlmIG5vZGUudHlwZSA9PSAnT1VUUFVUX01BVEVSSUFMJzpcXG4gICAgICAgIG91dHB1dCA9IG5vZGVcXG5cXG5pZiBidW1wIGFuZCBic2RmOlxcbiAgICBudC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXFwiKVxcblxcbmlmIGJzZGYgYW5kIG91dHB1dDpcXG4gICAgbnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuICAgIHByaW50KFxcXCJDb25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXFwiKVxcblxcbnByaW50KFxcXCJcXFxcbkZpbmFsIGxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05Y2RkY2VkMTU4YTE2YTdmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXG5Db25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXG5cXG5GaW5hbCBsaW5rczpcXG4gIFRleHR1cmUgQ29vcmRpbmF0ZS5HZW5lcmF0ZWQgLT4gTWFwcGluZy5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IE5vaXNlIFRleHR1cmUuVmVjdG9yXFxuICBNYXBwaW5nLlZlY3RvciAtPiBXYXZlIFRleHR1cmUuVmVjdG9yXFxuICBXYXZlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkFcXG4gIE5vaXNlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkJcXG4gIE1peC5SZXN1bHQgLT4gQ29sb3IgUmFtcC5GYWN0b3JcXG4gIENvbG9yIFJhbXAuQ29sb3IgLT4gUHJpbmNpcGxlZCBCU0RGLkJhc2UgQ29sb3JcXG4gIE5vaXNlIFRleHR1cmUuMDAxLkZhY3RvciAtPiBCdW1wLkhlaWdodFxcbiAgQnVtcC5Ob3JtYWwgLT4gUHJpbmNpcGxlZCBCU0RGLk5vcm1hbFxcbiAgUHJpbmNpcGxlZCBCU0RGLkJTREYgLT4gTWF0ZXJpYWwgT3V0cHV0LlN1cmZhY2VcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kLCBTdXphbm5lIG1hdGVyaWFsIGlzIGZpeGVkLiBOb3cgbGV0IG1lIHJlbmRlciB0byBjaGVjayBldmVyeXRoaW5nIGxvb2tzIGdvb2QuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWExYmRlODI5MDAwNTE1NjgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc3LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTFiZGU4MjkwMDA1MTU2OCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8ICDCtyDCtyAgICAgICAgIMK3IMK3IMK3IHxcXG4gIFJvdyAxOiB84oCiIMK3ICAgICDCtyDigKIg4oCiIMK3IMK3ICAgfFxcbiAgUm93IDI6IHzCtyDigKIg4peLIOKAoiDCtyAgICAgICAgICAgfFxcbiAgUm93IDM6IHzilpMg4paSIOKXjyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNDogfOKWiCDilpIg4pePIMK3ICAgICAgICAgICAgIHxcXG4gIFJvdyA1OiB84paTIOKXjyDilpMg4pePIOKXjyDCtyAgICAgICAgIHxcXG4gIFJvdyA2OiB8ICDil48g4paSIOKWkiDilogg4paSIOKWkyDil4sg4oCiICAgfFxcbiAgUm93IDc6IHzil4sg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDg6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paSIOKWkiDilpIgfFxcbiAgUm93IDk6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIgfFxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:18:33 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301511-uAn4NmNaEr1SnozfX569", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca383eead4ecab-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301511-uAn4NmNaEr1SnozfX569\",\"object\":\"chat.completion\",\"created\":1784301511,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":49111,\"completion_tokens\":22,\"total_tokens\":49133,\"cost\":0.00911277012,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":48448,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00911277012,\"upstream_inference_prompt_cost\":0.00904801092,\"upstream_inference_completions_cost\":0.0000647592},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKeyJpZCI6Imdlbi0xNzg0MzAxNTExLXVBbjRObU5hRXIxU25vemZYNTY5Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uIiwiY3JlYXRlZCI6MTc4NDMwMTUxMSwibW9kZWwiOiJ6LWFpL2dsbS01LjIiLCJwcm92aWRlciI6Ik5vdml0YSIsInN5c3RlbV9maW5nZXJwcmludCI6bnVsbCwic2VydmljZV90aWVyIjpudWxsLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibmF0aXZlX2ZpbmlzaF9yZWFzb24iOiJ0b29sX2NhbGxzIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLThiZjUwODFjMzdlZWJlYjYiLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0OTExMSwiY29tcGxldGlvbl90b2tlbnMiOjIyLCJ0b3RhbF90b2tlbnMiOjQ5MTMzLCJjb3N0IjowLjAwOTExMjc3MDEyLCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjQ4NDQ4LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAwOTExMjc3MDEyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA5MDQ4MDEwOTIsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMDA2NDc1OTJ9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-8bf5081c37eebeb6", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}], "tokens_in": 49111, "tokens_out": 22, "cost_usd": 0.00911277012, "cached_tokens": 48448}, "error": null}
{"ts": "2026-07-17T15:18:33.998765+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-8bf5081c37eebeb6", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:18:33.998765+00:00", "type": "tool_call", "id": "chatcmpl-tool-8bf5081c37eebeb6", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}
{"ts": "2026-07-17T15:18:34.477233+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-8bf5081c37eebeb6", "name": "get_screenshot_of_area_as_image", "text": "", "is_error": false, "has_image": true, "image_b64": "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"}
{"ts": "2026-07-17T15:18:47.362333+00:00", "type": "llm_call", "call_index": 63, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:18:34.480739+00:00", "finished_at": "2026-07-17T15:18:47.362333+00:00", "duration_s": 12.875, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}"}, {"role": "assistant", "content": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a1bde82900051568", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▒ ● ·             |\\n  Row 4: |█ ▒ ● ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8bf5081c37eebeb6", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8bf5081c37eebeb6", "content": ""}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:18:34.480739+00:00", "finished_at": "2026-07-17T15:18:47.361816+00:00", "duration_s": 12.875, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "184952", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9cddced158a16a7f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Connected bump to BSDF Normal\\\\nConnected BSDF to output\\\\n\\\\nFinal links:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n  Bump.Normal -> Principled BSDF.Normal\\\\n  Principled BSDF.BSDF -> Material Output.Surface\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good, Suzanne material is fixed. Now let me render to check everything looks good.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a1bde82900051568\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a1bde82900051568\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▒ ● ·             |\\\\n  Row 4: |█ ▒ ● ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"content\":\"\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWNkZGNlZDE1OGExNmE3ZiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBDb25uZWN0IGJ1bXAgdG8gQlNERiBOb3JtYWwgYW5kIEJTREYgdG8gb3V0cHV0XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5cXG4jIE1ha2Ugc3VyZSBidW1wIG5vcm1hbCBnb2VzIHRvIEJTREZcXG5idW1wID0gTm9uZVxcbmJzZGYgPSBOb25lXFxub3V0cHV0ID0gTm9uZVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ0JVTVAnOlxcbiAgICAgICAgYnVtcCA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ0JTREZfUFJJTkNJUExFRCc6XFxuICAgICAgICBic2RmID0gbm9kZVxcbiAgICBlbGlmIG5vZGUudHlwZSA9PSAnT1VUUFVUX01BVEVSSUFMJzpcXG4gICAgICAgIG91dHB1dCA9IG5vZGVcXG5cXG5pZiBidW1wIGFuZCBic2RmOlxcbiAgICBudC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXFwiKVxcblxcbmlmIGJzZGYgYW5kIG91dHB1dDpcXG4gICAgbnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuICAgIHByaW50KFxcXCJDb25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXFwiKVxcblxcbnByaW50KFxcXCJcXFxcbkZpbmFsIGxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05Y2RkY2VkMTU4YTE2YTdmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXG5Db25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXG5cXG5GaW5hbCBsaW5rczpcXG4gIFRleHR1cmUgQ29vcmRpbmF0ZS5HZW5lcmF0ZWQgLT4gTWFwcGluZy5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IE5vaXNlIFRleHR1cmUuVmVjdG9yXFxuICBNYXBwaW5nLlZlY3RvciAtPiBXYXZlIFRleHR1cmUuVmVjdG9yXFxuICBXYXZlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkFcXG4gIE5vaXNlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkJcXG4gIE1peC5SZXN1bHQgLT4gQ29sb3IgUmFtcC5GYWN0b3JcXG4gIENvbG9yIFJhbXAuQ29sb3IgLT4gUHJpbmNpcGxlZCBCU0RGLkJhc2UgQ29sb3JcXG4gIE5vaXNlIFRleHR1cmUuMDAxLkZhY3RvciAtPiBCdW1wLkhlaWdodFxcbiAgQnVtcC5Ob3JtYWwgLT4gUHJpbmNpcGxlZCBCU0RGLk5vcm1hbFxcbiAgUHJpbmNpcGxlZCBCU0RGLkJTREYgLT4gTWF0ZXJpYWwgT3V0cHV0LlN1cmZhY2VcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kLCBTdXphbm5lIG1hdGVyaWFsIGlzIGZpeGVkLiBOb3cgbGV0IG1lIHJlbmRlciB0byBjaGVjayBldmVyeXRoaW5nIGxvb2tzIGdvb2QuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWExYmRlODI5MDAwNTE1NjgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc3LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTFiZGU4MjkwMDA1MTU2OCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8ICDCtyDCtyAgICAgICAgIMK3IMK3IMK3IHxcXG4gIFJvdyAxOiB84oCiIMK3ICAgICDCtyDigKIg4oCiIMK3IMK3ICAgfFxcbiAgUm93IDI6IHzCtyDigKIg4peLIOKAoiDCtyAgICAgICAgICAgfFxcbiAgUm93IDM6IHzilpMg4paSIOKXjyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNDogfOKWiCDilpIg4pePIMK3ICAgICAgICAgICAgIHxcXG4gIFJvdyA1OiB84paTIOKXjyDilpMg4pePIOKXjyDCtyAgICAgICAgIHxcXG4gIFJvdyA2OiB8ICDil48g4paSIOKWkiDilogg4paSIOKWkyDil4sg4oCiICAgfFxcbiAgUm93IDc6IHzil4sg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDg6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paSIOKWkiDilpIgfFxcbiAgUm93IDk6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLThiZjUwODFjMzdlZWJlYjYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04YmY1MDgxYzM3ZWViZWI2IiwiY29udGVudCI6IiJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:18:37 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301515-AhIlAvFFNIeSmObE5Sxk", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca38553ff4d862-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301515-AhIlAvFFNIeSmObE5Sxk\",\"object\":\"chat.completion\",\"created\":1784301515,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-96f3c02259f22638\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check the right side of the image for green\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed color check on the right portion\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    if brightness < 0.05:\\\\n        continue\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check the right side specifically\\\\nright_g = 0\\\\nright_t = 0\\\\nfor y in range(h):\\\\n    for x in range(int(w*0.7), w, 3):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_t += 1\\\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\\\n                right_g += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_g/right_t:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":49137,\"completion_tokens\":464,\"total_tokens\":49601,\"cost\":0.00995009052,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":49088,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00995009052,\"upstream_inference_prompt_cost\":0.00858426012,\"upstream_inference_completions_cost\":0.0013658304},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTUxNS1BaElsQXZGRk5JZVNtT2JFNVN4ayIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDE1MTUsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIG9mIHRoZSBpbWFnZSBmb3IgZ3JlZW5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgRGV0YWlsZWQgY29sb3IgY2hlY2sgb24gdGhlIHJpZ2h0IHBvcnRpb25cXG5yZWRfY291bnQgPSAwXFxuZ3JlZW5fY291bnQgPSAwXFxud2FybV9jb3VudCA9IDBcXG50b3RhbCA9IDBcXG5cXG5mb3IgaSBpbiByYW5nZSgwLCBsZW4ocGl4ZWxzKSwgNCk6XFxuICAgIHIsIGcsIGIgPSBwaXhlbHNbaV0sIHBpeGVsc1tpKzFdLCBwaXhlbHNbaSsyXVxcbiAgICB0b3RhbCArPSAxXFxuICAgIGJyaWdodG5lc3MgPSAociArIGcgKyBiKSAvIDNcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgZWxpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgIGVsaWYgciA+IDAuMiBhbmQgZyA+IDAuMTUgYW5kIHIgPiBiICogMS4zOlxcbiAgICAgICAgd2FybV9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJSZWQ6IHsxMDAqcmVkX2NvdW50L3RvdGFsOi4xZn0lLCBHcmVlbjogezEwMCpncmVlbl9jb3VudC90b3RhbDouMWZ9JSwgV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIHNwZWNpZmljYWxseVxcbnJpZ2h0X2cgPSAwXFxucmlnaHRfdCA9IDBcXG5mb3IgeSBpbiByYW5nZShoKTpcXG4gICAgZm9yIHggaW4gcmFuZ2UoaW50KHcqMC43KSwgdywgMyk6XFxuICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICByLCBnLCBiID0gcGl4ZWxzW2lkeF0sIHBpeGVsc1tpZHgrMV0sIHBpeGVsc1tpZHgrMl1cXG4gICAgICAgICAgICByaWdodF90ICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4wOCBhbmQgZyA+IHIgKiAxLjE1IGFuZCBnID4gYiAqIDEuMTU6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2cgKz0gMVxcbnByaW50KGZcXFwiUmlnaHQgc2lkZSBncmVlbjogezEwMCpyaWdodF9nL3JpZ2h0X3Q6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0OTEzNywiY29tcGxldGlvbl90b2tlbnMiOjQ2NCwidG90YWxfdG9rZW5zIjo0OTYwMSwiY29zdCI6MC4wMDk5NTAwOTA1MiwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjo0OTA4OCwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMDk5NTAwOTA1MiwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwODU4NDI2MDEyLCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDEzNjU4MzA0fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-96f3c02259f22638", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Check the right side of the image for green\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview7.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Detailed color check on the right portion\nred_count = 0\ngreen_count = 0\nwarm_count = 0\ntotal = 0\n\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    total += 1\n    brightness = (r + g + b) / 3\n    if brightness < 0.05:\n        continue\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\n        red_count += 1\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\n        green_count += 1\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\n        warm_count += 1\n\nprint(f\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\")\n\n# Check the right side specifically\nright_g = 0\nright_t = 0\nfor y in range(h):\n    for x in range(int(w*0.7), w, 3):\n        idx = (y * w + x) * 4\n        if idx + 2 < len(pixels):\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\n            right_t += 1\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\n                right_g += 1\nprint(f\"Right side green: {100*right_g/right_t:.1f}%\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check the right side of the image for green\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed color check on the right portion\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    if brightness < 0.05:\\n        continue\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check the right side specifically\\nright_g = 0\\nright_t = 0\\nfor y in range(h):\\n    for x in range(int(w*0.7), w, 3):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_t += 1\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\n                right_g += 1\\nprint(f\\\"Right side green: {100*right_g/right_t:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 49137, "tokens_out": 464, "cost_usd": 0.00995009052, "cached_tokens": 49088}, "error": null}
{"ts": "2026-07-17T15:18:47.367056+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-96f3c02259f22638", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Check the right side of the image for green\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview7.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Detailed color check on the right portion\nred_count = 0\ngreen_count = 0\nwarm_count = 0\ntotal = 0\n\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    total += 1\n    brightness = (r + g + b) / 3\n    if brightness < 0.05:\n        continue\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\n        red_count += 1\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\n        green_count += 1\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\n        warm_count += 1\n\nprint(f\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\")\n\n# Check the right side specifically\nright_g = 0\nright_t = 0\nfor y in range(h):\n    for x in range(int(w*0.7), w, 3):\n        idx = (y * w + x) * 4\n        if idx + 2 < len(pixels):\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\n            right_t += 1\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\n                right_g += 1\nprint(f\"Right side green: {100*right_g/right_t:.1f}%\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check the right side of the image for green\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed color check on the right portion\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    if brightness < 0.05:\\n        continue\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check the right side specifically\\nright_g = 0\\nright_t = 0\\nfor y in range(h):\\n    for x in range(int(w*0.7), w, 3):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_t += 1\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\n                right_g += 1\\nprint(f\\\"Right side green: {100*right_g/right_t:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:18:47.367056+00:00", "type": "tool_call", "id": "chatcmpl-tool-96f3c02259f22638", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Check the right side of the image for green\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview7.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\n# Detailed color check on the right portion\nred_count = 0\ngreen_count = 0\nwarm_count = 0\ntotal = 0\n\nfor i in range(0, len(pixels), 4):\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\n    total += 1\n    brightness = (r + g + b) / 3\n    if brightness < 0.05:\n        continue\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\n        red_count += 1\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\n        green_count += 1\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\n        warm_count += 1\n\nprint(f\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\")\n\n# Check the right side specifically\nright_g = 0\nright_t = 0\nfor y in range(h):\n    for x in range(int(w*0.7), w, 3):\n        idx = (y * w + x) * 4\n        if idx + 2 < len(pixels):\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\n            right_t += 1\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\n                right_g += 1\nprint(f\"Right side green: {100*right_g/right_t:.1f}%\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check the right side of the image for green\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed color check on the right portion\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    if brightness < 0.05:\\n        continue\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check the right side specifically\\nright_g = 0\\nright_t = 0\\nfor y in range(h):\\n    for x in range(int(w*0.7), w, 3):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_t += 1\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\n                right_g += 1\\nprint(f\\\"Right side green: {100*right_g/right_t:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:18:48.867333+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-96f3c02259f22638", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\nRight side green: 10.8%\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:19:15.573057+00:00", "type": "llm_call", "call_index": 64, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:18:48.868333+00:00", "finished_at": "2026-07-17T15:19:15.572058+00:00", "duration_s": 26.71799999999348, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}"}, {"role": "assistant", "content": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a1bde82900051568", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▒ ● ·             |\\n  Row 4: |█ ▒ ● ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8bf5081c37eebeb6", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8bf5081c37eebeb6", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-96f3c02259f22638", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check the right side of the image for green\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed color check on the right portion\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    if brightness < 0.05:\\n        continue\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check the right side specifically\\nright_g = 0\\nright_t = 0\\nfor y in range(h):\\n    for x in range(int(w*0.7), w, 3):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_t += 1\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\n                right_g += 1\\nprint(f\\\"Right side green: {100*right_g/right_t:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-96f3c02259f22638", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\nRight side green: 10.8%\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:18:48.868333+00:00", "finished_at": "2026-07-17T15:19:15.571054+00:00", "duration_s": 26.703000000008615, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "186716", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9cddced158a16a7f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Connected bump to BSDF Normal\\\\nConnected BSDF to output\\\\n\\\\nFinal links:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n  Bump.Normal -> Principled BSDF.Normal\\\\n  Principled BSDF.BSDF -> Material Output.Surface\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good, Suzanne material is fixed. Now let me render to check everything looks good.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a1bde82900051568\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a1bde82900051568\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▒ ● ·             |\\\\n  Row 4: |█ ▒ ● ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-96f3c02259f22638\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check the right side of the image for green\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed color check on the right portion\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    if brightness < 0.05:\\\\n        continue\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check the right side specifically\\\\nright_g = 0\\\\nright_t = 0\\\\nfor y in range(h):\\\\n    for x in range(int(w*0.7), w, 3):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_t += 1\\\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\\\n                right_g += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_g/right_t:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-96f3c02259f22638\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\\\nRight side green: 10.8%\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWNkZGNlZDE1OGExNmE3ZiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBDb25uZWN0IGJ1bXAgdG8gQlNERiBOb3JtYWwgYW5kIEJTREYgdG8gb3V0cHV0XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5cXG4jIE1ha2Ugc3VyZSBidW1wIG5vcm1hbCBnb2VzIHRvIEJTREZcXG5idW1wID0gTm9uZVxcbmJzZGYgPSBOb25lXFxub3V0cHV0ID0gTm9uZVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ0JVTVAnOlxcbiAgICAgICAgYnVtcCA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ0JTREZfUFJJTkNJUExFRCc6XFxuICAgICAgICBic2RmID0gbm9kZVxcbiAgICBlbGlmIG5vZGUudHlwZSA9PSAnT1VUUFVUX01BVEVSSUFMJzpcXG4gICAgICAgIG91dHB1dCA9IG5vZGVcXG5cXG5pZiBidW1wIGFuZCBic2RmOlxcbiAgICBudC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXFwiKVxcblxcbmlmIGJzZGYgYW5kIG91dHB1dDpcXG4gICAgbnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuICAgIHByaW50KFxcXCJDb25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXFwiKVxcblxcbnByaW50KFxcXCJcXFxcbkZpbmFsIGxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05Y2RkY2VkMTU4YTE2YTdmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXG5Db25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXG5cXG5GaW5hbCBsaW5rczpcXG4gIFRleHR1cmUgQ29vcmRpbmF0ZS5HZW5lcmF0ZWQgLT4gTWFwcGluZy5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IE5vaXNlIFRleHR1cmUuVmVjdG9yXFxuICBNYXBwaW5nLlZlY3RvciAtPiBXYXZlIFRleHR1cmUuVmVjdG9yXFxuICBXYXZlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkFcXG4gIE5vaXNlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkJcXG4gIE1peC5SZXN1bHQgLT4gQ29sb3IgUmFtcC5GYWN0b3JcXG4gIENvbG9yIFJhbXAuQ29sb3IgLT4gUHJpbmNpcGxlZCBCU0RGLkJhc2UgQ29sb3JcXG4gIE5vaXNlIFRleHR1cmUuMDAxLkZhY3RvciAtPiBCdW1wLkhlaWdodFxcbiAgQnVtcC5Ob3JtYWwgLT4gUHJpbmNpcGxlZCBCU0RGLk5vcm1hbFxcbiAgUHJpbmNpcGxlZCBCU0RGLkJTREYgLT4gTWF0ZXJpYWwgT3V0cHV0LlN1cmZhY2VcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kLCBTdXphbm5lIG1hdGVyaWFsIGlzIGZpeGVkLiBOb3cgbGV0IG1lIHJlbmRlciB0byBjaGVjayBldmVyeXRoaW5nIGxvb2tzIGdvb2QuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWExYmRlODI5MDAwNTE1NjgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc3LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTFiZGU4MjkwMDA1MTU2OCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8ICDCtyDCtyAgICAgICAgIMK3IMK3IMK3IHxcXG4gIFJvdyAxOiB84oCiIMK3ICAgICDCtyDigKIg4oCiIMK3IMK3ICAgfFxcbiAgUm93IDI6IHzCtyDigKIg4peLIOKAoiDCtyAgICAgICAgICAgfFxcbiAgUm93IDM6IHzilpMg4paSIOKXjyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNDogfOKWiCDilpIg4pePIMK3ICAgICAgICAgICAgIHxcXG4gIFJvdyA1OiB84paTIOKXjyDilpMg4pePIOKXjyDCtyAgICAgICAgIHxcXG4gIFJvdyA2OiB8ICDil48g4paSIOKWkiDilogg4paSIOKWkyDil4sg4oCiICAgfFxcbiAgUm93IDc6IHzil4sg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDg6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paSIOKWkiDilpIgfFxcbiAgUm93IDk6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLThiZjUwODFjMzdlZWJlYjYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04YmY1MDgxYzM3ZWViZWI2IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIG9mIHRoZSBpbWFnZSBmb3IgZ3JlZW5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgRGV0YWlsZWQgY29sb3IgY2hlY2sgb24gdGhlIHJpZ2h0IHBvcnRpb25cXG5yZWRfY291bnQgPSAwXFxuZ3JlZW5fY291bnQgPSAwXFxud2FybV9jb3VudCA9IDBcXG50b3RhbCA9IDBcXG5cXG5mb3IgaSBpbiByYW5nZSgwLCBsZW4ocGl4ZWxzKSwgNCk6XFxuICAgIHIsIGcsIGIgPSBwaXhlbHNbaV0sIHBpeGVsc1tpKzFdLCBwaXhlbHNbaSsyXVxcbiAgICB0b3RhbCArPSAxXFxuICAgIGJyaWdodG5lc3MgPSAociArIGcgKyBiKSAvIDNcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgZWxpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgIGVsaWYgciA+IDAuMiBhbmQgZyA+IDAuMTUgYW5kIHIgPiBiICogMS4zOlxcbiAgICAgICAgd2FybV9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJSZWQ6IHsxMDAqcmVkX2NvdW50L3RvdGFsOi4xZn0lLCBHcmVlbjogezEwMCpncmVlbl9jb3VudC90b3RhbDouMWZ9JSwgV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIHNwZWNpZmljYWxseVxcbnJpZ2h0X2cgPSAwXFxucmlnaHRfdCA9IDBcXG5mb3IgeSBpbiByYW5nZShoKTpcXG4gICAgZm9yIHggaW4gcmFuZ2UoaW50KHcqMC43KSwgdywgMyk6XFxuICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICByLCBnLCBiID0gcGl4ZWxzW2lkeF0sIHBpeGVsc1tpZHgrMV0sIHBpeGVsc1tpZHgrMl1cXG4gICAgICAgICAgICByaWdodF90ICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4wOCBhbmQgZyA+IHIgKiAxLjE1IGFuZCBnID4gYiAqIDEuMTU6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2cgKz0gMVxcbnByaW50KGZcXFwiUmlnaHQgc2lkZSBncmVlbjogezEwMCpyaWdodF9nL3JpZ2h0X3Q6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkOiAxNC4wJSwgR3JlZW46IDMuOCUsIFdhcm06IDMxLjQlXFxuUmlnaHQgc2lkZSBncmVlbjogMTAuOCVcXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:18:51 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301529-IR7DImeyVbQEjgGq9wiO", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca38af3955cc48-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301529-IR7DImeyVbQEjgGq9wiO\",\"object\":\"chat.completion\",\"created\":1784301529,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-99ced8845b19cf57\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# CANDLESTICK with candle - additional classical prop\\\\n# Justifies the warm light source\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"CandlestickMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the candlestick (radius, height) — lathed\\\\nstick_profile = [\\\\n    (0.00, 0.00),    # center bottom\\\\n    (0.12, 0.00),    # base edge\\\\n    (0.13, 0.01),    # base lip\\\\n    (0.12, 0.03),    # \\\\n    (0.08, 0.04),    # base to stem\\\\n    (0.05, 0.06),    # stem base\\\\n    (0.04, 0.15),    # stem\\\\n    (0.04, 0.25),    # stem\\\\n    (0.05, 0.30),    # mid decorative\\\\n    (0.04, 0.35),    # \\\\n    (0.035, 0.40),   # upper stem\\\\n    (0.05, 0.44),    # candle cup base\\\\n    (0.06, 0.46),    # cup\\\\n    (0.055, 0.48),   # cup lip\\\\n    (0.04, 0.50),    # cup inner\\\\n    (0.00, 0.50),    # center top\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in stick_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = stick_profile[ri]\\\\n    rb, _ = stick_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nstick_obj = bpy.data.objects.new(\\\\\\\"Candlestick\\\\\\\", mesh)\\\\nlink_obj(stick_obj)\\\\nstick_obj.location = (-1.6, 0.8, 0.0)\\\\nbpy.context.view_layer.objects.active = stick_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = stick_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# Candle\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\\\ncandle = bpy.context.active_object\\\\ncandle.name = \\\\\\\"Candle\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Candle flame - a small emissive shape\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\\\nflame = bpy.context.active_object\\\\nflame.name = \\\\\\\"CandleFlame\\\\\\\"\\\\nflame.scale = (0.6, 0.6, 1.8)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nprint(\\\\\\\"Candlestick with candle and flame built.\\\\\\\")\\\\nresult = {\\\\\\\"candlestick\\\\\\\": stick_obj.name, \\\\\\\"candle\\\\\\\": candle.name, \\\\\\\"flame\\\\\\\": flame.name}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":49666,\"completion_tokens\":1032,\"total_tokens\":50698,\"cost\":0.01211751672,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":49088,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.01211751672,\"upstream_inference_prompt_cost\":0.00907972152,\"upstream_inference_completions_cost\":0.0030377952},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTUyOS1JUjdESW1leVZiUUVqZ0dxOXdpTyIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDE1MjksIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kIC0gZ3JlZW4gaXMgbm93IHZpc2libGUgb24gdGhlIHJpZ2h0IHNpZGUuIFRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgd2l0aCByZWQgb24gdGhlIGxlZnQsIGdyZWVuIG9uIHRoZSByaWdodCAoQ29ybmVsbCBib3ggcGFsZXR0ZSksIHdhcm0gbGlnaHQsIGFuZCBkYXJrIHNoYWRvd3MuIExldCBtZSBub3cgYWRkIHNvbWUgZmluYWwgcG9saXNoOiBhIGNhbmRsZXN0aWNrIGFzIGFuIGFkZGl0aW9uYWwgY2xhc3NpY2FsIHByb3AgKHdoaWNoIGFsc28ganVzdGlmaWVzIHRoZSB3YXJtIGxpZ2h0IHNvdXJjZSksIGFuZCBtYWtlIGFkanVzdG1lbnRzIHRvIHRoZSBTdXphbm5lIGJ1c3QgcG9zaXRpb25pbmcuIiwicmVmdXNhbCI6bnVsbCwicmVhc29uaW5nIjpudWxsLCJ0b29sX2NhbGxzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJpbmRleCI6MCwiaWQiOiJjaGF0Y21wbC10b29sLTk5Y2VkODg0NWIxOWNmNTciLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ0FORExFU1RJQ0sgd2l0aCBjYW5kbGUgLSBhZGRpdGlvbmFsIGNsYXNzaWNhbCBwcm9wXFxuIyBKdXN0aWZpZXMgdGhlIHdhcm0gbGlnaHQgc291cmNlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQ2FuZGxlc3RpY2tNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSBjYW5kbGVzdGljayAocmFkaXVzLCBoZWlnaHQpIOKAlCBsYXRoZWRcXG5zdGlja19wcm9maWxlID0gW1xcbiAgICAoMC4wMCwgMC4wMCksICAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4xMiwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjEzLCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMiwgMC4wMyksICAgICMgXFxuICAgICgwLjA4LCAwLjA0KSwgICAgIyBiYXNlIHRvIHN0ZW1cXG4gICAgKDAuMDUsIDAuMDYpLCAgICAjIHN0ZW0gYmFzZVxcbiAgICAoMC4wNCwgMC4xNSksICAgICMgc3RlbVxcbiAgICAoMC4wNCwgMC4yNSksICAgICMgc3RlbVxcbiAgICAoMC4wNSwgMC4zMCksICAgICMgbWlkIGRlY29yYXRpdmVcXG4gICAgKDAuMDQsIDAuMzUpLCAgICAjIFxcbiAgICAoMC4wMzUsIDAuNDApLCAgICMgdXBwZXIgc3RlbVxcbiAgICAoMC4wNSwgMC40NCksICAgICMgY2FuZGxlIGN1cCBiYXNlXFxuICAgICgwLjA2LCAwLjQ2KSwgICAgIyBjdXBcXG4gICAgKDAuMDU1LCAwLjQ4KSwgICAjIGN1cCBsaXBcXG4gICAgKDAuMDQsIDAuNTApLCAgICAjIGN1cCBpbm5lclxcbiAgICAoMC4wMCwgMC41MCksICAgICMgY2VudGVyIHRvcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBzdGlja19wcm9maWxlOlxcbiAgICByaW5nID0gW11cXG4gICAgaWYgciA8IDAuMDAxOlxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4oYWxsX3ZlcnRzKSAtIDEpOlxcbiAgICByaW5nX2EgPSBhbGxfdmVydHNbcmldXFxuICAgIHJpbmdfYiA9IGFsbF92ZXJ0c1tyaSArIDFdXFxuICAgIHJhLCBfID0gc3RpY2tfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBzdGlja19wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuc3RpY2tfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkNhbmRsZXN0aWNrXFxcIiwgbWVzaClcXG5saW5rX29iaihzdGlja19vYmopXFxuc3RpY2tfb2JqLmxvY2F0aW9uID0gKC0xLjYsIDAuOCwgMC4wKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBzdGlja19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IHN0aWNrX29iai5tb2RpZmllcnMubmV3KFxcXCJTdWJzdXJmXFxcIiwgJ1NVQlNVUkYnKVxcbm1vZC5sZXZlbHMgPSAxXFxubW9kLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuIyBDYW5kbGVcXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX2N5bGluZGVyX2FkZChyYWRpdXM9MC4wMzUsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgtMS42LCAwLjgsIDAuNTc1KSlcXG5jYW5kbGUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuY2FuZGxlLm5hbWUgPSBcXFwiQ2FuZGxlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBDYW5kbGUgZmxhbWUgLSBhIHNtYWxsIGVtaXNzaXZlIHNoYXBlXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz0wLjAzLCBzZWdtZW50cz0xNiwgcmluZ19jb3VudD04LCBsb2NhdGlvbj0oLTEuNiwgMC44LCAwLjcwKSlcXG5mbGFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5mbGFtZS5uYW1lID0gXFxcIkNhbmRsZUZsYW1lXFxcIlxcbmZsYW1lLnNjYWxlID0gKDAuNiwgMC42LCAxLjgpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1GYWxzZSwgc2NhbGU9VHJ1ZSlcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbnByaW50KFxcXCJDYW5kbGVzdGljayB3aXRoIGNhbmRsZSBhbmQgZmxhbWUgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNhbmRsZXN0aWNrXFxcIjogc3RpY2tfb2JqLm5hbWUsIFxcXCJjYW5kbGVcXFwiOiBjYW5kbGUubmFtZSwgXFxcImZsYW1lXFxcIjogZmxhbWUubmFtZX1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo0OTY2NiwiY29tcGxldGlvbl90b2tlbnMiOjEwMzIsInRvdGFsX3Rva2VucyI6NTA2OTgsImNvc3QiOjAuMDEyMTE3NTE2NzIsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6NDkwODgsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDEyMTE3NTE2NzIsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDkwNzk3MjE1MiwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAzMDM3Nzk1Mn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.", "tool_calls": [{"id": "chatcmpl-tool-99ced8845b19cf57", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# CANDLESTICK with candle - additional classical prop\n# Justifies the warm light source\n# ============================================================\nmesh = bpy.data.meshes.new(\"CandlestickMesh\")\nbm = bmesh.new()\n\n# Profile of the candlestick (radius, height) — lathed\nstick_profile = [\n    (0.00, 0.00),    # center bottom\n    (0.12, 0.00),    # base edge\n    (0.13, 0.01),    # base lip\n    (0.12, 0.03),    # \n    (0.08, 0.04),    # base to stem\n    (0.05, 0.06),    # stem base\n    (0.04, 0.15),    # stem\n    (0.04, 0.25),    # stem\n    (0.05, 0.30),    # mid decorative\n    (0.04, 0.35),    # \n    (0.035, 0.40),   # upper stem\n    (0.05, 0.44),    # candle cup base\n    (0.06, 0.46),    # cup\n    (0.055, 0.48),   # cup lip\n    (0.04, 0.50),    # cup inner\n    (0.00, 0.50),    # center top\n]\n\nsegments = 48\nall_verts = []\nfor r, h in stick_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = stick_profile[ri]\n    rb, _ = stick_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nstick_obj = bpy.data.objects.new(\"Candlestick\", mesh)\nlink_obj(stick_obj)\nstick_obj.location = (-1.6, 0.8, 0.0)\nbpy.context.view_layer.objects.active = stick_obj\nbpy.ops.object.shade_smooth()\n\nmod = stick_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\n# Candle\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\ncandle = bpy.context.active_object\ncandle.name = \"Candle\"\nbpy.ops.object.shade_smooth()\n\n# Candle flame - a small emissive shape\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\nflame = bpy.context.active_object\nflame.name = \"CandleFlame\"\nflame.scale = (0.6, 0.6, 1.8)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\nbpy.ops.object.shade_smooth()\n\nprint(\"Candlestick with candle and flame built.\")\nresult = {\"candlestick\": stick_obj.name, \"candle\": candle.name, \"flame\": flame.name}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# CANDLESTICK with candle - additional classical prop\\n# Justifies the warm light source\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"CandlestickMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the candlestick (radius, height) — lathed\\nstick_profile = [\\n    (0.00, 0.00),    # center bottom\\n    (0.12, 0.00),    # base edge\\n    (0.13, 0.01),    # base lip\\n    (0.12, 0.03),    # \\n    (0.08, 0.04),    # base to stem\\n    (0.05, 0.06),    # stem base\\n    (0.04, 0.15),    # stem\\n    (0.04, 0.25),    # stem\\n    (0.05, 0.30),    # mid decorative\\n    (0.04, 0.35),    # \\n    (0.035, 0.40),   # upper stem\\n    (0.05, 0.44),    # candle cup base\\n    (0.06, 0.46),    # cup\\n    (0.055, 0.48),   # cup lip\\n    (0.04, 0.50),    # cup inner\\n    (0.00, 0.50),    # center top\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in stick_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = stick_profile[ri]\\n    rb, _ = stick_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nstick_obj = bpy.data.objects.new(\\\"Candlestick\\\", mesh)\\nlink_obj(stick_obj)\\nstick_obj.location = (-1.6, 0.8, 0.0)\\nbpy.context.view_layer.objects.active = stick_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = stick_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# Candle\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\ncandle = bpy.context.active_object\\ncandle.name = \\\"Candle\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Candle flame - a small emissive shape\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\nflame = bpy.context.active_object\\nflame.name = \\\"CandleFlame\\\"\\nflame.scale = (0.6, 0.6, 1.8)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\nbpy.ops.object.shade_smooth()\\n\\nprint(\\\"Candlestick with candle and flame built.\\\")\\nresult = {\\\"candlestick\\\": stick_obj.name, \\\"candle\\\": candle.name, \\\"flame\\\": flame.name}\\n\"}", "parse_error": null}], "tokens_in": 49666, "tokens_out": 1032, "cost_usd": 0.01211751672, "cached_tokens": 49088}, "error": null}
{"ts": "2026-07-17T15:19:15.577123+00:00", "type": "assistant", "text": "Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.", "tool_calls": [{"id": "chatcmpl-tool-99ced8845b19cf57", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# CANDLESTICK with candle - additional classical prop\n# Justifies the warm light source\n# ============================================================\nmesh = bpy.data.meshes.new(\"CandlestickMesh\")\nbm = bmesh.new()\n\n# Profile of the candlestick (radius, height) — lathed\nstick_profile = [\n    (0.00, 0.00),    # center bottom\n    (0.12, 0.00),    # base edge\n    (0.13, 0.01),    # base lip\n    (0.12, 0.03),    # \n    (0.08, 0.04),    # base to stem\n    (0.05, 0.06),    # stem base\n    (0.04, 0.15),    # stem\n    (0.04, 0.25),    # stem\n    (0.05, 0.30),    # mid decorative\n    (0.04, 0.35),    # \n    (0.035, 0.40),   # upper stem\n    (0.05, 0.44),    # candle cup base\n    (0.06, 0.46),    # cup\n    (0.055, 0.48),   # cup lip\n    (0.04, 0.50),    # cup inner\n    (0.00, 0.50),    # center top\n]\n\nsegments = 48\nall_verts = []\nfor r, h in stick_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = stick_profile[ri]\n    rb, _ = stick_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nstick_obj = bpy.data.objects.new(\"Candlestick\", mesh)\nlink_obj(stick_obj)\nstick_obj.location = (-1.6, 0.8, 0.0)\nbpy.context.view_layer.objects.active = stick_obj\nbpy.ops.object.shade_smooth()\n\nmod = stick_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\n# Candle\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\ncandle = bpy.context.active_object\ncandle.name = \"Candle\"\nbpy.ops.object.shade_smooth()\n\n# Candle flame - a small emissive shape\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\nflame = bpy.context.active_object\nflame.name = \"CandleFlame\"\nflame.scale = (0.6, 0.6, 1.8)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\nbpy.ops.object.shade_smooth()\n\nprint(\"Candlestick with candle and flame built.\")\nresult = {\"candlestick\": stick_obj.name, \"candle\": candle.name, \"flame\": flame.name}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# CANDLESTICK with candle - additional classical prop\\n# Justifies the warm light source\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"CandlestickMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the candlestick (radius, height) — lathed\\nstick_profile = [\\n    (0.00, 0.00),    # center bottom\\n    (0.12, 0.00),    # base edge\\n    (0.13, 0.01),    # base lip\\n    (0.12, 0.03),    # \\n    (0.08, 0.04),    # base to stem\\n    (0.05, 0.06),    # stem base\\n    (0.04, 0.15),    # stem\\n    (0.04, 0.25),    # stem\\n    (0.05, 0.30),    # mid decorative\\n    (0.04, 0.35),    # \\n    (0.035, 0.40),   # upper stem\\n    (0.05, 0.44),    # candle cup base\\n    (0.06, 0.46),    # cup\\n    (0.055, 0.48),   # cup lip\\n    (0.04, 0.50),    # cup inner\\n    (0.00, 0.50),    # center top\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in stick_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = stick_profile[ri]\\n    rb, _ = stick_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nstick_obj = bpy.data.objects.new(\\\"Candlestick\\\", mesh)\\nlink_obj(stick_obj)\\nstick_obj.location = (-1.6, 0.8, 0.0)\\nbpy.context.view_layer.objects.active = stick_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = stick_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# Candle\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\ncandle = bpy.context.active_object\\ncandle.name = \\\"Candle\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Candle flame - a small emissive shape\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\nflame = bpy.context.active_object\\nflame.name = \\\"CandleFlame\\\"\\nflame.scale = (0.6, 0.6, 1.8)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\nbpy.ops.object.shade_smooth()\\n\\nprint(\\\"Candlestick with candle and flame built.\\\")\\nresult = {\\\"candlestick\\\": stick_obj.name, \\\"candle\\\": candle.name, \\\"flame\\\": flame.name}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:19:15.577123+00:00", "type": "tool_call", "id": "chatcmpl-tool-99ced8845b19cf57", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport bmesh\nimport math\nfrom mathutils import Vector\n\ndef link_obj(obj):\n    bpy.context.scene.collection.objects.link(obj)\n    return obj\n\n# ============================================================\n# CANDLESTICK with candle - additional classical prop\n# Justifies the warm light source\n# ============================================================\nmesh = bpy.data.meshes.new(\"CandlestickMesh\")\nbm = bmesh.new()\n\n# Profile of the candlestick (radius, height) — lathed\nstick_profile = [\n    (0.00, 0.00),    # center bottom\n    (0.12, 0.00),    # base edge\n    (0.13, 0.01),    # base lip\n    (0.12, 0.03),    # \n    (0.08, 0.04),    # base to stem\n    (0.05, 0.06),    # stem base\n    (0.04, 0.15),    # stem\n    (0.04, 0.25),    # stem\n    (0.05, 0.30),    # mid decorative\n    (0.04, 0.35),    # \n    (0.035, 0.40),   # upper stem\n    (0.05, 0.44),    # candle cup base\n    (0.06, 0.46),    # cup\n    (0.055, 0.48),   # cup lip\n    (0.04, 0.50),    # cup inner\n    (0.00, 0.50),    # center top\n]\n\nsegments = 48\nall_verts = []\nfor r, h in stick_profile:\n    ring = []\n    if r < 0.001:\n        v = bm.verts.new((0, 0, h))\n        ring = [v] * segments\n    else:\n        for i in range(segments):\n            angle = (i / segments) * math.tau\n            x = r * math.cos(angle)\n            y = r * math.sin(angle)\n            v = bm.verts.new((x, y, h))\n            ring.append(v)\n    all_verts.append(ring)\n\nbm.verts.ensure_lookup_table()\n\nfor ri in range(len(all_verts) - 1):\n    ring_a = all_verts[ri]\n    ring_b = all_verts[ri + 1]\n    ra, _ = stick_profile[ri]\n    rb, _ = stick_profile[ri + 1]\n    for i in range(segments):\n        j = (i + 1) % segments\n        if ra < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\n        elif rb < 0.001:\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\n        else:\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\n\nbm.normal_update()\nbm.to_mesh(mesh)\nbm.free()\n\nstick_obj = bpy.data.objects.new(\"Candlestick\", mesh)\nlink_obj(stick_obj)\nstick_obj.location = (-1.6, 0.8, 0.0)\nbpy.context.view_layer.objects.active = stick_obj\nbpy.ops.object.shade_smooth()\n\nmod = stick_obj.modifiers.new(\"Subsurf\", 'SUBSURF')\nmod.levels = 1\nmod.render_levels = 2\n\n# Candle\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\ncandle = bpy.context.active_object\ncandle.name = \"Candle\"\nbpy.ops.object.shade_smooth()\n\n# Candle flame - a small emissive shape\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\nflame = bpy.context.active_object\nflame.name = \"CandleFlame\"\nflame.scale = (0.6, 0.6, 1.8)\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\nbpy.ops.object.shade_smooth()\n\nprint(\"Candlestick with candle and flame built.\")\nresult = {\"candlestick\": stick_obj.name, \"candle\": candle.name, \"flame\": flame.name}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# CANDLESTICK with candle - additional classical prop\\n# Justifies the warm light source\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"CandlestickMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the candlestick (radius, height) — lathed\\nstick_profile = [\\n    (0.00, 0.00),    # center bottom\\n    (0.12, 0.00),    # base edge\\n    (0.13, 0.01),    # base lip\\n    (0.12, 0.03),    # \\n    (0.08, 0.04),    # base to stem\\n    (0.05, 0.06),    # stem base\\n    (0.04, 0.15),    # stem\\n    (0.04, 0.25),    # stem\\n    (0.05, 0.30),    # mid decorative\\n    (0.04, 0.35),    # \\n    (0.035, 0.40),   # upper stem\\n    (0.05, 0.44),    # candle cup base\\n    (0.06, 0.46),    # cup\\n    (0.055, 0.48),   # cup lip\\n    (0.04, 0.50),    # cup inner\\n    (0.00, 0.50),    # center top\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in stick_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = stick_profile[ri]\\n    rb, _ = stick_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nstick_obj = bpy.data.objects.new(\\\"Candlestick\\\", mesh)\\nlink_obj(stick_obj)\\nstick_obj.location = (-1.6, 0.8, 0.0)\\nbpy.context.view_layer.objects.active = stick_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = stick_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# Candle\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\ncandle = bpy.context.active_object\\ncandle.name = \\\"Candle\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Candle flame - a small emissive shape\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\nflame = bpy.context.active_object\\nflame.name = \\\"CandleFlame\\\"\\nflame.scale = (0.6, 0.6, 1.8)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\nbpy.ops.object.shade_smooth()\\n\\nprint(\\\"Candlestick with candle and flame built.\\\")\\nresult = {\\\"candlestick\\\": stick_obj.name, \\\"candle\\\": candle.name, \\\"flame\\\": flame.name}\\n\"}"}
{"ts": "2026-07-17T15:19:16.182195+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-99ced8845b19cf57", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"candlestick\": \"Candlestick\",\n    \"candle\": \"Candle\",\n    \"flame\": \"CandleFlame\"\n  },\n  \"stdout\": \"Candlestick with candle and flame built.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:19:39.100680+00:00", "type": "llm_call", "call_index": 65, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:19:16.276453+00:00", "finished_at": "2026-07-17T15:19:39.099682+00:00", "duration_s": 22.812999999994645, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}"}, {"role": "assistant", "content": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a1bde82900051568", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▒ ● ·             |\\n  Row 4: |█ ▒ ● ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8bf5081c37eebeb6", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8bf5081c37eebeb6", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-96f3c02259f22638", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check the right side of the image for green\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed color check on the right portion\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    if brightness < 0.05:\\n        continue\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check the right side specifically\\nright_g = 0\\nright_t = 0\\nfor y in range(h):\\n    for x in range(int(w*0.7), w, 3):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_t += 1\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\n                right_g += 1\\nprint(f\\\"Right side green: {100*right_g/right_t:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-96f3c02259f22638", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\nRight side green: 10.8%\\n\"\n}"}, {"role": "assistant", "content": "Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.", "tool_calls": [{"id": "chatcmpl-tool-99ced8845b19cf57", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# CANDLESTICK with candle - additional classical prop\\n# Justifies the warm light source\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"CandlestickMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the candlestick (radius, height) — lathed\\nstick_profile = [\\n    (0.00, 0.00),    # center bottom\\n    (0.12, 0.00),    # base edge\\n    (0.13, 0.01),    # base lip\\n    (0.12, 0.03),    # \\n    (0.08, 0.04),    # base to stem\\n    (0.05, 0.06),    # stem base\\n    (0.04, 0.15),    # stem\\n    (0.04, 0.25),    # stem\\n    (0.05, 0.30),    # mid decorative\\n    (0.04, 0.35),    # \\n    (0.035, 0.40),   # upper stem\\n    (0.05, 0.44),    # candle cup base\\n    (0.06, 0.46),    # cup\\n    (0.055, 0.48),   # cup lip\\n    (0.04, 0.50),    # cup inner\\n    (0.00, 0.50),    # center top\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in stick_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = stick_profile[ri]\\n    rb, _ = stick_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nstick_obj = bpy.data.objects.new(\\\"Candlestick\\\", mesh)\\nlink_obj(stick_obj)\\nstick_obj.location = (-1.6, 0.8, 0.0)\\nbpy.context.view_layer.objects.active = stick_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = stick_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# Candle\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\ncandle = bpy.context.active_object\\ncandle.name = \\\"Candle\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Candle flame - a small emissive shape\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\nflame = bpy.context.active_object\\nflame.name = \\\"CandleFlame\\\"\\nflame.scale = (0.6, 0.6, 1.8)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\nbpy.ops.object.shade_smooth()\\n\\nprint(\\\"Candlestick with candle and flame built.\\\")\\nresult = {\\\"candlestick\\\": stick_obj.name, \\\"candle\\\": candle.name, \\\"flame\\\": flame.name}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-99ced8845b19cf57", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"candlestick\": \"Candlestick\",\n    \"candle\": \"Candle\",\n    \"flame\": \"CandleFlame\"\n  },\n  \"stdout\": \"Candlestick with candle and flame built.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:19:16.276453+00:00", "finished_at": "2026-07-17T15:19:39.098675+00:00", "duration_s": 22.812999999994645, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "190724", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9cddced158a16a7f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Connected bump to BSDF Normal\\\\nConnected BSDF to output\\\\n\\\\nFinal links:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n  Bump.Normal -> Principled BSDF.Normal\\\\n  Principled BSDF.BSDF -> Material Output.Surface\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good, Suzanne material is fixed. Now let me render to check everything looks good.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a1bde82900051568\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a1bde82900051568\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▒ ● ·             |\\\\n  Row 4: |█ ▒ ● ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-96f3c02259f22638\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check the right side of the image for green\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed color check on the right portion\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    if brightness < 0.05:\\\\n        continue\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check the right side specifically\\\\nright_g = 0\\\\nright_t = 0\\\\nfor y in range(h):\\\\n    for x in range(int(w*0.7), w, 3):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_t += 1\\\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\\\n                right_g += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_g/right_t:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-96f3c02259f22638\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\\\nRight side green: 10.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-99ced8845b19cf57\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# CANDLESTICK with candle - additional classical prop\\\\n# Justifies the warm light source\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"CandlestickMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the candlestick (radius, height) — lathed\\\\nstick_profile = [\\\\n    (0.00, 0.00),    # center bottom\\\\n    (0.12, 0.00),    # base edge\\\\n    (0.13, 0.01),    # base lip\\\\n    (0.12, 0.03),    # \\\\n    (0.08, 0.04),    # base to stem\\\\n    (0.05, 0.06),    # stem base\\\\n    (0.04, 0.15),    # stem\\\\n    (0.04, 0.25),    # stem\\\\n    (0.05, 0.30),    # mid decorative\\\\n    (0.04, 0.35),    # \\\\n    (0.035, 0.40),   # upper stem\\\\n    (0.05, 0.44),    # candle cup base\\\\n    (0.06, 0.46),    # cup\\\\n    (0.055, 0.48),   # cup lip\\\\n    (0.04, 0.50),    # cup inner\\\\n    (0.00, 0.50),    # center top\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in stick_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = stick_profile[ri]\\\\n    rb, _ = stick_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nstick_obj = bpy.data.objects.new(\\\\\\\"Candlestick\\\\\\\", mesh)\\\\nlink_obj(stick_obj)\\\\nstick_obj.location = (-1.6, 0.8, 0.0)\\\\nbpy.context.view_layer.objects.active = stick_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = stick_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# Candle\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\\\ncandle = bpy.context.active_object\\\\ncandle.name = \\\\\\\"Candle\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Candle flame - a small emissive shape\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\\\nflame = bpy.context.active_object\\\\nflame.name = \\\\\\\"CandleFlame\\\\\\\"\\\\nflame.scale = (0.6, 0.6, 1.8)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nprint(\\\\\\\"Candlestick with candle and flame built.\\\\\\\")\\\\nresult = {\\\\\\\"candlestick\\\\\\\": stick_obj.name, \\\\\\\"candle\\\\\\\": candle.name, \\\\\\\"flame\\\\\\\": flame.name}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-99ced8845b19cf57\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"candlestick\\\": \\\"Candlestick\\\",\\n    \\\"candle\\\": \\\"Candle\\\",\\n    \\\"flame\\\": \\\"CandleFlame\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick with candle and flame built.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWNkZGNlZDE1OGExNmE3ZiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBDb25uZWN0IGJ1bXAgdG8gQlNERiBOb3JtYWwgYW5kIEJTREYgdG8gb3V0cHV0XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5cXG4jIE1ha2Ugc3VyZSBidW1wIG5vcm1hbCBnb2VzIHRvIEJTREZcXG5idW1wID0gTm9uZVxcbmJzZGYgPSBOb25lXFxub3V0cHV0ID0gTm9uZVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ0JVTVAnOlxcbiAgICAgICAgYnVtcCA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ0JTREZfUFJJTkNJUExFRCc6XFxuICAgICAgICBic2RmID0gbm9kZVxcbiAgICBlbGlmIG5vZGUudHlwZSA9PSAnT1VUUFVUX01BVEVSSUFMJzpcXG4gICAgICAgIG91dHB1dCA9IG5vZGVcXG5cXG5pZiBidW1wIGFuZCBic2RmOlxcbiAgICBudC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXFwiKVxcblxcbmlmIGJzZGYgYW5kIG91dHB1dDpcXG4gICAgbnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuICAgIHByaW50KFxcXCJDb25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXFwiKVxcblxcbnByaW50KFxcXCJcXFxcbkZpbmFsIGxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05Y2RkY2VkMTU4YTE2YTdmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXG5Db25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXG5cXG5GaW5hbCBsaW5rczpcXG4gIFRleHR1cmUgQ29vcmRpbmF0ZS5HZW5lcmF0ZWQgLT4gTWFwcGluZy5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IE5vaXNlIFRleHR1cmUuVmVjdG9yXFxuICBNYXBwaW5nLlZlY3RvciAtPiBXYXZlIFRleHR1cmUuVmVjdG9yXFxuICBXYXZlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkFcXG4gIE5vaXNlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkJcXG4gIE1peC5SZXN1bHQgLT4gQ29sb3IgUmFtcC5GYWN0b3JcXG4gIENvbG9yIFJhbXAuQ29sb3IgLT4gUHJpbmNpcGxlZCBCU0RGLkJhc2UgQ29sb3JcXG4gIE5vaXNlIFRleHR1cmUuMDAxLkZhY3RvciAtPiBCdW1wLkhlaWdodFxcbiAgQnVtcC5Ob3JtYWwgLT4gUHJpbmNpcGxlZCBCU0RGLk5vcm1hbFxcbiAgUHJpbmNpcGxlZCBCU0RGLkJTREYgLT4gTWF0ZXJpYWwgT3V0cHV0LlN1cmZhY2VcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kLCBTdXphbm5lIG1hdGVyaWFsIGlzIGZpeGVkLiBOb3cgbGV0IG1lIHJlbmRlciB0byBjaGVjayBldmVyeXRoaW5nIGxvb2tzIGdvb2QuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWExYmRlODI5MDAwNTE1NjgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc3LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTFiZGU4MjkwMDA1MTU2OCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8ICDCtyDCtyAgICAgICAgIMK3IMK3IMK3IHxcXG4gIFJvdyAxOiB84oCiIMK3ICAgICDCtyDigKIg4oCiIMK3IMK3ICAgfFxcbiAgUm93IDI6IHzCtyDigKIg4peLIOKAoiDCtyAgICAgICAgICAgfFxcbiAgUm93IDM6IHzilpMg4paSIOKXjyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNDogfOKWiCDilpIg4pePIMK3ICAgICAgICAgICAgIHxcXG4gIFJvdyA1OiB84paTIOKXjyDilpMg4pePIOKXjyDCtyAgICAgICAgIHxcXG4gIFJvdyA2OiB8ICDil48g4paSIOKWkiDilogg4paSIOKWkyDil4sg4oCiICAgfFxcbiAgUm93IDc6IHzil4sg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDg6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paSIOKWkiDilpIgfFxcbiAgUm93IDk6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLThiZjUwODFjMzdlZWJlYjYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04YmY1MDgxYzM3ZWViZWI2IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIG9mIHRoZSBpbWFnZSBmb3IgZ3JlZW5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgRGV0YWlsZWQgY29sb3IgY2hlY2sgb24gdGhlIHJpZ2h0IHBvcnRpb25cXG5yZWRfY291bnQgPSAwXFxuZ3JlZW5fY291bnQgPSAwXFxud2FybV9jb3VudCA9IDBcXG50b3RhbCA9IDBcXG5cXG5mb3IgaSBpbiByYW5nZSgwLCBsZW4ocGl4ZWxzKSwgNCk6XFxuICAgIHIsIGcsIGIgPSBwaXhlbHNbaV0sIHBpeGVsc1tpKzFdLCBwaXhlbHNbaSsyXVxcbiAgICB0b3RhbCArPSAxXFxuICAgIGJyaWdodG5lc3MgPSAociArIGcgKyBiKSAvIDNcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgZWxpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgIGVsaWYgciA+IDAuMiBhbmQgZyA+IDAuMTUgYW5kIHIgPiBiICogMS4zOlxcbiAgICAgICAgd2FybV9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJSZWQ6IHsxMDAqcmVkX2NvdW50L3RvdGFsOi4xZn0lLCBHcmVlbjogezEwMCpncmVlbl9jb3VudC90b3RhbDouMWZ9JSwgV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIHNwZWNpZmljYWxseVxcbnJpZ2h0X2cgPSAwXFxucmlnaHRfdCA9IDBcXG5mb3IgeSBpbiByYW5nZShoKTpcXG4gICAgZm9yIHggaW4gcmFuZ2UoaW50KHcqMC43KSwgdywgMyk6XFxuICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICByLCBnLCBiID0gcGl4ZWxzW2lkeF0sIHBpeGVsc1tpZHgrMV0sIHBpeGVsc1tpZHgrMl1cXG4gICAgICAgICAgICByaWdodF90ICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4wOCBhbmQgZyA+IHIgKiAxLjE1IGFuZCBnID4gYiAqIDEuMTU6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2cgKz0gMVxcbnByaW50KGZcXFwiUmlnaHQgc2lkZSBncmVlbjogezEwMCpyaWdodF9nL3JpZ2h0X3Q6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkOiAxNC4wJSwgR3JlZW46IDMuOCUsIFdhcm06IDMxLjQlXFxuUmlnaHQgc2lkZSBncmVlbjogMTAuOCVcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kIC0gZ3JlZW4gaXMgbm93IHZpc2libGUgb24gdGhlIHJpZ2h0IHNpZGUuIFRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgd2l0aCByZWQgb24gdGhlIGxlZnQsIGdyZWVuIG9uIHRoZSByaWdodCAoQ29ybmVsbCBib3ggcGFsZXR0ZSksIHdhcm0gbGlnaHQsIGFuZCBkYXJrIHNoYWRvd3MuIExldCBtZSBub3cgYWRkIHNvbWUgZmluYWwgcG9saXNoOiBhIGNhbmRsZXN0aWNrIGFzIGFuIGFkZGl0aW9uYWwgY2xhc3NpY2FsIHByb3AgKHdoaWNoIGFsc28ganVzdGlmaWVzIHRoZSB3YXJtIGxpZ2h0IHNvdXJjZSksIGFuZCBtYWtlIGFkanVzdG1lbnRzIHRvIHRoZSBTdXphbm5lIGJ1c3QgcG9zaXRpb25pbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk5Y2VkODg0NWIxOWNmNTciLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ0FORExFU1RJQ0sgd2l0aCBjYW5kbGUgLSBhZGRpdGlvbmFsIGNsYXNzaWNhbCBwcm9wXFxuIyBKdXN0aWZpZXMgdGhlIHdhcm0gbGlnaHQgc291cmNlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQ2FuZGxlc3RpY2tNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSBjYW5kbGVzdGljayAocmFkaXVzLCBoZWlnaHQpIOKAlCBsYXRoZWRcXG5zdGlja19wcm9maWxlID0gW1xcbiAgICAoMC4wMCwgMC4wMCksICAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4xMiwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjEzLCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMiwgMC4wMyksICAgICMgXFxuICAgICgwLjA4LCAwLjA0KSwgICAgIyBiYXNlIHRvIHN0ZW1cXG4gICAgKDAuMDUsIDAuMDYpLCAgICAjIHN0ZW0gYmFzZVxcbiAgICAoMC4wNCwgMC4xNSksICAgICMgc3RlbVxcbiAgICAoMC4wNCwgMC4yNSksICAgICMgc3RlbVxcbiAgICAoMC4wNSwgMC4zMCksICAgICMgbWlkIGRlY29yYXRpdmVcXG4gICAgKDAuMDQsIDAuMzUpLCAgICAjIFxcbiAgICAoMC4wMzUsIDAuNDApLCAgICMgdXBwZXIgc3RlbVxcbiAgICAoMC4wNSwgMC40NCksICAgICMgY2FuZGxlIGN1cCBiYXNlXFxuICAgICgwLjA2LCAwLjQ2KSwgICAgIyBjdXBcXG4gICAgKDAuMDU1LCAwLjQ4KSwgICAjIGN1cCBsaXBcXG4gICAgKDAuMDQsIDAuNTApLCAgICAjIGN1cCBpbm5lclxcbiAgICAoMC4wMCwgMC41MCksICAgICMgY2VudGVyIHRvcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBzdGlja19wcm9maWxlOlxcbiAgICByaW5nID0gW11cXG4gICAgaWYgciA8IDAuMDAxOlxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4oYWxsX3ZlcnRzKSAtIDEpOlxcbiAgICByaW5nX2EgPSBhbGxfdmVydHNbcmldXFxuICAgIHJpbmdfYiA9IGFsbF92ZXJ0c1tyaSArIDFdXFxuICAgIHJhLCBfID0gc3RpY2tfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBzdGlja19wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuc3RpY2tfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkNhbmRsZXN0aWNrXFxcIiwgbWVzaClcXG5saW5rX29iaihzdGlja19vYmopXFxuc3RpY2tfb2JqLmxvY2F0aW9uID0gKC0xLjYsIDAuOCwgMC4wKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBzdGlja19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IHN0aWNrX29iai5tb2RpZmllcnMubmV3KFxcXCJTdWJzdXJmXFxcIiwgJ1NVQlNVUkYnKVxcbm1vZC5sZXZlbHMgPSAxXFxubW9kLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuIyBDYW5kbGVcXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX2N5bGluZGVyX2FkZChyYWRpdXM9MC4wMzUsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgtMS42LCAwLjgsIDAuNTc1KSlcXG5jYW5kbGUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuY2FuZGxlLm5hbWUgPSBcXFwiQ2FuZGxlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBDYW5kbGUgZmxhbWUgLSBhIHNtYWxsIGVtaXNzaXZlIHNoYXBlXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz0wLjAzLCBzZWdtZW50cz0xNiwgcmluZ19jb3VudD04LCBsb2NhdGlvbj0oLTEuNiwgMC44LCAwLjcwKSlcXG5mbGFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5mbGFtZS5uYW1lID0gXFxcIkNhbmRsZUZsYW1lXFxcIlxcbmZsYW1lLnNjYWxlID0gKDAuNiwgMC42LCAxLjgpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1GYWxzZSwgc2NhbGU9VHJ1ZSlcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbnByaW50KFxcXCJDYW5kbGVzdGljayB3aXRoIGNhbmRsZSBhbmQgZmxhbWUgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNhbmRsZXN0aWNrXFxcIjogc3RpY2tfb2JqLm5hbWUsIFxcXCJjYW5kbGVcXFwiOiBjYW5kbGUubmFtZSwgXFxcImZsYW1lXFxcIjogZmxhbWUubmFtZX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05OWNlZDg4NDViMTljZjU3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjYW5kbGVzdGlja1wiOiBcIkNhbmRsZXN0aWNrXCIsXG4gICAgXCJjYW5kbGVcIjogXCJDYW5kbGVcIixcbiAgICBcImZsYW1lXCI6IFwiQ2FuZGxlRmxhbWVcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbmRsZXN0aWNrIHdpdGggY2FuZGxlIGFuZCBmbGFtZSBidWlsdC5cXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:19:19 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301557-HNo4MIJkH5hUl3V34q9V", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca395a7d72e8a4-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301557-HNo4MIJkH5hUl3V34q9V\",\"object\":\"chat.completion\",\"created\":1784301557,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-86253733bb060d5b\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- Candlestick: Aged brass/bronze ---\\\\nmat, nt = create_material(\\\\\\\"M_CandlestickBrass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 5.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 40.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Candlestick\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle: Waxed off-white ---\\\\nmat, nt = create_material(\\\\\\\"M_Candle\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.5\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Candle\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle flame: Emissive ---\\\\nmat, nt = create_material(\\\\\\\"M_CandleFlame\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\\\nemission.inputs['Strength'].default_value = 15.0\\\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"CandleFlame\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Add a point light at the flame for actual illumination\\\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\\\nflame_light = bpy.context.active_object\\\\nflame_light.name = \\\\\\\"CandleLight\\\\\\\"\\\\nflame_light.data.energy = 50\\\\nflame_light.data.color = (1.0, 0.7, 0.3)\\\\nflame_light.data.shadow_soft_size = 0.05\\\\n\\\\nprint(\\\\\\\"Candlestick, candle, and flame materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":50765,\"completion_tokens\":928,\"total_tokens\":51693,\"cost\":0.01240141356,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":49664,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.01240141356,\"upstream_inference_prompt_cost\":0.00966975276,\"upstream_inference_completions_cost\":0.0027316608},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTU1Ny1ITm80TUlKa0g1aFVsM1YzNHE5ViIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDE1NTcsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC04NjI1MzczM2JiMDYwZDViIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIENhbmRsZXN0aWNrOiBBZ2VkIGJyYXNzL2Jyb256ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZXN0aWNrQnJhc3NcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDIsIDAuMjAsIDEuMCkgICMgYnJhc3NcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjM1XFxuXFxuIyBQYXRpbmEgdmFyaWF0aW9uXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNS4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MiwgMC4yMCwgMS4wKSAgIyBicmFzc1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjM1LCAwLjIwLCAxLjApICAjIHBhdGluYVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkNhbmRsZXN0aWNrXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGU6IFdheGVkIG9mZi13aGl0ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MiwgMC43MiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGUgZmxhbWU6IEVtaXNzaXZlIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQ2FuZGxlRmxhbWVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuZW1pc3Npb24gPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVFbWlzc2lvbicsICgyMDAsIDApKVxcbmVtaXNzaW9uLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDEuMCwgMC43LCAwLjMsIDEuMCkgICMgd2FybSBmbGFtZVxcbmVtaXNzaW9uLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm50LmxpbmtzLm5ldyhlbWlzc2lvbi5vdXRwdXRzWydFbWlzc2lvbiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlRmxhbWVcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgQWRkIGEgcG9pbnQgbGlnaHQgYXQgdGhlIGZsYW1lIGZvciBhY3R1YWwgaWxsdW1pbmF0aW9uXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J1BPSU5UJywgbG9jYXRpb249KC0xLjYsIDAuOCwgMC43MikpXFxuZmxhbWVfbGlnaHQgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxhbWVfbGlnaHQubmFtZSA9IFxcXCJDYW5kbGVMaWdodFxcXCJcXG5mbGFtZV9saWdodC5kYXRhLmVuZXJneSA9IDUwXFxuZmxhbWVfbGlnaHQuZGF0YS5jb2xvciA9ICgxLjAsIDAuNywgMC4zKVxcbmZsYW1lX2xpZ2h0LmRhdGEuc2hhZG93X3NvZnRfc2l6ZSA9IDAuMDVcXG5cXG5wcmludChcXFwiQ2FuZGxlc3RpY2ssIGNhbmRsZSwgYW5kIGZsYW1lIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjUwNzY1LCJjb21wbGV0aW9uX3Rva2VucyI6OTI4LCJ0b3RhbF90b2tlbnMiOjUxNjkzLCJjb3N0IjowLjAxMjQwMTQxMzU2LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjQ5NjY0LCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAxMjQwMTQxMzU2LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA5NjY5NzUyNzYsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMjczMTY2MDh9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-86253733bb060d5b", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- Candlestick: Aged brass/bronze ---\nmat, nt = create_material(\"M_CandlestickBrass\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.35\n\n# Patina variation\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 5.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.2\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 40.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"Candlestick\"].data.materials.append(mat)\n\n# --- Candle: Waxed off-white ---\nmat, nt = create_material(\"M_Candle\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.5\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"Candle\"].data.materials.append(mat)\n\n# --- Candle flame: Emissive ---\nmat, nt = create_material(\"M_CandleFlame\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\nemission.inputs['Strength'].default_value = 15.0\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\nbpy.data.objects[\"CandleFlame\"].data.materials.append(mat)\n\n# Add a point light at the flame for actual illumination\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\nflame_light = bpy.context.active_object\nflame_light.name = \"CandleLight\"\nflame_light.data.energy = 50\nflame_light.data.color = (1.0, 0.7, 0.3)\nflame_light.data.shadow_soft_size = 0.05\n\nprint(\"Candlestick, candle, and flame materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- Candlestick: Aged brass/bronze ---\\nmat, nt = create_material(\\\"M_CandlestickBrass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 5.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 40.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Candlestick\\\"].data.materials.append(mat)\\n\\n# --- Candle: Waxed off-white ---\\nmat, nt = create_material(\\\"M_Candle\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.5\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Candle\\\"].data.materials.append(mat)\\n\\n# --- Candle flame: Emissive ---\\nmat, nt = create_material(\\\"M_CandleFlame\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\nemission.inputs['Strength'].default_value = 15.0\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\nbpy.data.objects[\\\"CandleFlame\\\"].data.materials.append(mat)\\n\\n# Add a point light at the flame for actual illumination\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\nflame_light = bpy.context.active_object\\nflame_light.name = \\\"CandleLight\\\"\\nflame_light.data.energy = 50\\nflame_light.data.color = (1.0, 0.7, 0.3)\\nflame_light.data.shadow_soft_size = 0.05\\n\\nprint(\\\"Candlestick, candle, and flame materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 50765, "tokens_out": 928, "cost_usd": 0.01240141356, "cached_tokens": 49664}, "error": null}
{"ts": "2026-07-17T15:19:39.104694+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-86253733bb060d5b", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- Candlestick: Aged brass/bronze ---\nmat, nt = create_material(\"M_CandlestickBrass\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.35\n\n# Patina variation\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 5.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.2\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 40.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"Candlestick\"].data.materials.append(mat)\n\n# --- Candle: Waxed off-white ---\nmat, nt = create_material(\"M_Candle\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.5\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"Candle\"].data.materials.append(mat)\n\n# --- Candle flame: Emissive ---\nmat, nt = create_material(\"M_CandleFlame\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\nemission.inputs['Strength'].default_value = 15.0\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\nbpy.data.objects[\"CandleFlame\"].data.materials.append(mat)\n\n# Add a point light at the flame for actual illumination\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\nflame_light = bpy.context.active_object\nflame_light.name = \"CandleLight\"\nflame_light.data.energy = 50\nflame_light.data.color = (1.0, 0.7, 0.3)\nflame_light.data.shadow_soft_size = 0.05\n\nprint(\"Candlestick, candle, and flame materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- Candlestick: Aged brass/bronze ---\\nmat, nt = create_material(\\\"M_CandlestickBrass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 5.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 40.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Candlestick\\\"].data.materials.append(mat)\\n\\n# --- Candle: Waxed off-white ---\\nmat, nt = create_material(\\\"M_Candle\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.5\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Candle\\\"].data.materials.append(mat)\\n\\n# --- Candle flame: Emissive ---\\nmat, nt = create_material(\\\"M_CandleFlame\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\nemission.inputs['Strength'].default_value = 15.0\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\nbpy.data.objects[\\\"CandleFlame\\\"].data.materials.append(mat)\\n\\n# Add a point light at the flame for actual illumination\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\nflame_light = bpy.context.active_object\\nflame_light.name = \\\"CandleLight\\\"\\nflame_light.data.energy = 50\\nflame_light.data.color = (1.0, 0.7, 0.3)\\nflame_light.data.shadow_soft_size = 0.05\\n\\nprint(\\\"Candlestick, candle, and flame materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:19:39.104694+00:00", "type": "tool_call", "id": "chatcmpl-tool-86253733bb060d5b", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\n\ndef create_material(name):\n    mat = bpy.data.materials.new(name)\n    mat.use_nodes = True\n    nt = mat.node_tree\n    for n in list(nt.nodes):\n        nt.nodes.remove(n)\n    return mat, nt\n\ndef add_node(nt, node_type, location=(0,0)):\n    n = nt.nodes.new(node_type)\n    n.location = location\n    return n\n\n# --- Candlestick: Aged brass/bronze ---\nmat, nt = create_material(\"M_CandlestickBrass\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\nbsdf.inputs['Metallic'].default_value = 1.0\nbsdf.inputs['Roughness'].default_value = 0.35\n\n# Patina variation\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\nnoise.inputs['Scale'].default_value = 5.0\nnoise.inputs['Detail'].default_value = 4.0\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\n\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\nbump.inputs['Strength'].default_value = 0.2\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\nnoise2.inputs['Scale'].default_value = 40.0\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\n\nbpy.data.objects[\"Candlestick\"].data.materials.append(mat)\n\n# --- Candle: Waxed off-white ---\nmat, nt = create_material(\"M_Candle\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\nbsdf.inputs['Roughness'].default_value = 0.5\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\nbpy.data.objects[\"Candle\"].data.materials.append(mat)\n\n# --- Candle flame: Emissive ---\nmat, nt = create_material(\"M_CandleFlame\")\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\nemission.inputs['Strength'].default_value = 15.0\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\nbpy.data.objects[\"CandleFlame\"].data.materials.append(mat)\n\n# Add a point light at the flame for actual illumination\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\nflame_light = bpy.context.active_object\nflame_light.name = \"CandleLight\"\nflame_light.data.energy = 50\nflame_light.data.color = (1.0, 0.7, 0.3)\nflame_light.data.shadow_soft_size = 0.05\n\nprint(\"Candlestick, candle, and flame materials created.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- Candlestick: Aged brass/bronze ---\\nmat, nt = create_material(\\\"M_CandlestickBrass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 5.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 40.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Candlestick\\\"].data.materials.append(mat)\\n\\n# --- Candle: Waxed off-white ---\\nmat, nt = create_material(\\\"M_Candle\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.5\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Candle\\\"].data.materials.append(mat)\\n\\n# --- Candle flame: Emissive ---\\nmat, nt = create_material(\\\"M_CandleFlame\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\nemission.inputs['Strength'].default_value = 15.0\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\nbpy.data.objects[\\\"CandleFlame\\\"].data.materials.append(mat)\\n\\n# Add a point light at the flame for actual illumination\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\nflame_light = bpy.context.active_object\\nflame_light.name = \\\"CandleLight\\\"\\nflame_light.data.energy = 50\\nflame_light.data.color = (1.0, 0.7, 0.3)\\nflame_light.data.shadow_soft_size = 0.05\\n\\nprint(\\\"Candlestick, candle, and flame materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:19:39.721676+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-86253733bb060d5b", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Candlestick, candle, and flame materials created.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:19:52.867193+00:00", "type": "llm_call", "call_index": 66, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:19:39.724688+00:00", "finished_at": "2026-07-17T15:19:52.866194+00:00", "duration_s": 13.14100000000326, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}"}, {"role": "assistant", "content": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a1bde82900051568", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▒ ● ·             |\\n  Row 4: |█ ▒ ● ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8bf5081c37eebeb6", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8bf5081c37eebeb6", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-96f3c02259f22638", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check the right side of the image for green\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed color check on the right portion\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    if brightness < 0.05:\\n        continue\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check the right side specifically\\nright_g = 0\\nright_t = 0\\nfor y in range(h):\\n    for x in range(int(w*0.7), w, 3):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_t += 1\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\n                right_g += 1\\nprint(f\\\"Right side green: {100*right_g/right_t:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-96f3c02259f22638", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\nRight side green: 10.8%\\n\"\n}"}, {"role": "assistant", "content": "Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.", "tool_calls": [{"id": "chatcmpl-tool-99ced8845b19cf57", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# CANDLESTICK with candle - additional classical prop\\n# Justifies the warm light source\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"CandlestickMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the candlestick (radius, height) — lathed\\nstick_profile = [\\n    (0.00, 0.00),    # center bottom\\n    (0.12, 0.00),    # base edge\\n    (0.13, 0.01),    # base lip\\n    (0.12, 0.03),    # \\n    (0.08, 0.04),    # base to stem\\n    (0.05, 0.06),    # stem base\\n    (0.04, 0.15),    # stem\\n    (0.04, 0.25),    # stem\\n    (0.05, 0.30),    # mid decorative\\n    (0.04, 0.35),    # \\n    (0.035, 0.40),   # upper stem\\n    (0.05, 0.44),    # candle cup base\\n    (0.06, 0.46),    # cup\\n    (0.055, 0.48),   # cup lip\\n    (0.04, 0.50),    # cup inner\\n    (0.00, 0.50),    # center top\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in stick_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = stick_profile[ri]\\n    rb, _ = stick_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nstick_obj = bpy.data.objects.new(\\\"Candlestick\\\", mesh)\\nlink_obj(stick_obj)\\nstick_obj.location = (-1.6, 0.8, 0.0)\\nbpy.context.view_layer.objects.active = stick_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = stick_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# Candle\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\ncandle = bpy.context.active_object\\ncandle.name = \\\"Candle\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Candle flame - a small emissive shape\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\nflame = bpy.context.active_object\\nflame.name = \\\"CandleFlame\\\"\\nflame.scale = (0.6, 0.6, 1.8)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\nbpy.ops.object.shade_smooth()\\n\\nprint(\\\"Candlestick with candle and flame built.\\\")\\nresult = {\\\"candlestick\\\": stick_obj.name, \\\"candle\\\": candle.name, \\\"flame\\\": flame.name}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-99ced8845b19cf57", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"candlestick\": \"Candlestick\",\n    \"candle\": \"Candle\",\n    \"flame\": \"CandleFlame\"\n  },\n  \"stdout\": \"Candlestick with candle and flame built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-86253733bb060d5b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- Candlestick: Aged brass/bronze ---\\nmat, nt = create_material(\\\"M_CandlestickBrass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 5.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 40.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Candlestick\\\"].data.materials.append(mat)\\n\\n# --- Candle: Waxed off-white ---\\nmat, nt = create_material(\\\"M_Candle\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.5\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Candle\\\"].data.materials.append(mat)\\n\\n# --- Candle flame: Emissive ---\\nmat, nt = create_material(\\\"M_CandleFlame\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\nemission.inputs['Strength'].default_value = 15.0\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\nbpy.data.objects[\\\"CandleFlame\\\"].data.materials.append(mat)\\n\\n# Add a point light at the flame for actual illumination\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\nflame_light = bpy.context.active_object\\nflame_light.name = \\\"CandleLight\\\"\\nflame_light.data.energy = 50\\nflame_light.data.color = (1.0, 0.7, 0.3)\\nflame_light.data.shadow_soft_size = 0.05\\n\\nprint(\\\"Candlestick, candle, and flame materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-86253733bb060d5b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Candlestick, candle, and flame materials created.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:19:39.724688+00:00", "finished_at": "2026-07-17T15:19:52.865188+00:00", "duration_s": 13.14100000000326, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "194235", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9cddced158a16a7f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Connected bump to BSDF Normal\\\\nConnected BSDF to output\\\\n\\\\nFinal links:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n  Bump.Normal -> Principled BSDF.Normal\\\\n  Principled BSDF.BSDF -> Material Output.Surface\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good, Suzanne material is fixed. Now let me render to check everything looks good.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a1bde82900051568\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a1bde82900051568\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▒ ● ·             |\\\\n  Row 4: |█ ▒ ● ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-96f3c02259f22638\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check the right side of the image for green\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed color check on the right portion\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    if brightness < 0.05:\\\\n        continue\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check the right side specifically\\\\nright_g = 0\\\\nright_t = 0\\\\nfor y in range(h):\\\\n    for x in range(int(w*0.7), w, 3):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_t += 1\\\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\\\n                right_g += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_g/right_t:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-96f3c02259f22638\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\\\nRight side green: 10.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-99ced8845b19cf57\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# CANDLESTICK with candle - additional classical prop\\\\n# Justifies the warm light source\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"CandlestickMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the candlestick (radius, height) — lathed\\\\nstick_profile = [\\\\n    (0.00, 0.00),    # center bottom\\\\n    (0.12, 0.00),    # base edge\\\\n    (0.13, 0.01),    # base lip\\\\n    (0.12, 0.03),    # \\\\n    (0.08, 0.04),    # base to stem\\\\n    (0.05, 0.06),    # stem base\\\\n    (0.04, 0.15),    # stem\\\\n    (0.04, 0.25),    # stem\\\\n    (0.05, 0.30),    # mid decorative\\\\n    (0.04, 0.35),    # \\\\n    (0.035, 0.40),   # upper stem\\\\n    (0.05, 0.44),    # candle cup base\\\\n    (0.06, 0.46),    # cup\\\\n    (0.055, 0.48),   # cup lip\\\\n    (0.04, 0.50),    # cup inner\\\\n    (0.00, 0.50),    # center top\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in stick_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = stick_profile[ri]\\\\n    rb, _ = stick_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nstick_obj = bpy.data.objects.new(\\\\\\\"Candlestick\\\\\\\", mesh)\\\\nlink_obj(stick_obj)\\\\nstick_obj.location = (-1.6, 0.8, 0.0)\\\\nbpy.context.view_layer.objects.active = stick_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = stick_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# Candle\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\\\ncandle = bpy.context.active_object\\\\ncandle.name = \\\\\\\"Candle\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Candle flame - a small emissive shape\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\\\nflame = bpy.context.active_object\\\\nflame.name = \\\\\\\"CandleFlame\\\\\\\"\\\\nflame.scale = (0.6, 0.6, 1.8)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nprint(\\\\\\\"Candlestick with candle and flame built.\\\\\\\")\\\\nresult = {\\\\\\\"candlestick\\\\\\\": stick_obj.name, \\\\\\\"candle\\\\\\\": candle.name, \\\\\\\"flame\\\\\\\": flame.name}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-99ced8845b19cf57\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"candlestick\\\": \\\"Candlestick\\\",\\n    \\\"candle\\\": \\\"Candle\\\",\\n    \\\"flame\\\": \\\"CandleFlame\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick with candle and flame built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-86253733bb060d5b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- Candlestick: Aged brass/bronze ---\\\\nmat, nt = create_material(\\\\\\\"M_CandlestickBrass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 5.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 40.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Candlestick\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle: Waxed off-white ---\\\\nmat, nt = create_material(\\\\\\\"M_Candle\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.5\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Candle\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle flame: Emissive ---\\\\nmat, nt = create_material(\\\\\\\"M_CandleFlame\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\\\nemission.inputs['Strength'].default_value = 15.0\\\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"CandleFlame\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Add a point light at the flame for actual illumination\\\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\\\nflame_light = bpy.context.active_object\\\\nflame_light.name = \\\\\\\"CandleLight\\\\\\\"\\\\nflame_light.data.energy = 50\\\\nflame_light.data.color = (1.0, 0.7, 0.3)\\\\nflame_light.data.shadow_soft_size = 0.05\\\\n\\\\nprint(\\\\\\\"Candlestick, candle, and flame materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-86253733bb060d5b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick, candle, and flame materials created.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWNkZGNlZDE1OGExNmE3ZiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBDb25uZWN0IGJ1bXAgdG8gQlNERiBOb3JtYWwgYW5kIEJTREYgdG8gb3V0cHV0XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5cXG4jIE1ha2Ugc3VyZSBidW1wIG5vcm1hbCBnb2VzIHRvIEJTREZcXG5idW1wID0gTm9uZVxcbmJzZGYgPSBOb25lXFxub3V0cHV0ID0gTm9uZVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ0JVTVAnOlxcbiAgICAgICAgYnVtcCA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ0JTREZfUFJJTkNJUExFRCc6XFxuICAgICAgICBic2RmID0gbm9kZVxcbiAgICBlbGlmIG5vZGUudHlwZSA9PSAnT1VUUFVUX01BVEVSSUFMJzpcXG4gICAgICAgIG91dHB1dCA9IG5vZGVcXG5cXG5pZiBidW1wIGFuZCBic2RmOlxcbiAgICBudC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXFwiKVxcblxcbmlmIGJzZGYgYW5kIG91dHB1dDpcXG4gICAgbnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuICAgIHByaW50KFxcXCJDb25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXFwiKVxcblxcbnByaW50KFxcXCJcXFxcbkZpbmFsIGxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05Y2RkY2VkMTU4YTE2YTdmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXG5Db25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXG5cXG5GaW5hbCBsaW5rczpcXG4gIFRleHR1cmUgQ29vcmRpbmF0ZS5HZW5lcmF0ZWQgLT4gTWFwcGluZy5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IE5vaXNlIFRleHR1cmUuVmVjdG9yXFxuICBNYXBwaW5nLlZlY3RvciAtPiBXYXZlIFRleHR1cmUuVmVjdG9yXFxuICBXYXZlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkFcXG4gIE5vaXNlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkJcXG4gIE1peC5SZXN1bHQgLT4gQ29sb3IgUmFtcC5GYWN0b3JcXG4gIENvbG9yIFJhbXAuQ29sb3IgLT4gUHJpbmNpcGxlZCBCU0RGLkJhc2UgQ29sb3JcXG4gIE5vaXNlIFRleHR1cmUuMDAxLkZhY3RvciAtPiBCdW1wLkhlaWdodFxcbiAgQnVtcC5Ob3JtYWwgLT4gUHJpbmNpcGxlZCBCU0RGLk5vcm1hbFxcbiAgUHJpbmNpcGxlZCBCU0RGLkJTREYgLT4gTWF0ZXJpYWwgT3V0cHV0LlN1cmZhY2VcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kLCBTdXphbm5lIG1hdGVyaWFsIGlzIGZpeGVkLiBOb3cgbGV0IG1lIHJlbmRlciB0byBjaGVjayBldmVyeXRoaW5nIGxvb2tzIGdvb2QuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWExYmRlODI5MDAwNTE1NjgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc3LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTFiZGU4MjkwMDA1MTU2OCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8ICDCtyDCtyAgICAgICAgIMK3IMK3IMK3IHxcXG4gIFJvdyAxOiB84oCiIMK3ICAgICDCtyDigKIg4oCiIMK3IMK3ICAgfFxcbiAgUm93IDI6IHzCtyDigKIg4peLIOKAoiDCtyAgICAgICAgICAgfFxcbiAgUm93IDM6IHzilpMg4paSIOKXjyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNDogfOKWiCDilpIg4pePIMK3ICAgICAgICAgICAgIHxcXG4gIFJvdyA1OiB84paTIOKXjyDilpMg4pePIOKXjyDCtyAgICAgICAgIHxcXG4gIFJvdyA2OiB8ICDil48g4paSIOKWkiDilogg4paSIOKWkyDil4sg4oCiICAgfFxcbiAgUm93IDc6IHzil4sg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDg6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paSIOKWkiDilpIgfFxcbiAgUm93IDk6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLThiZjUwODFjMzdlZWJlYjYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04YmY1MDgxYzM3ZWViZWI2IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIG9mIHRoZSBpbWFnZSBmb3IgZ3JlZW5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgRGV0YWlsZWQgY29sb3IgY2hlY2sgb24gdGhlIHJpZ2h0IHBvcnRpb25cXG5yZWRfY291bnQgPSAwXFxuZ3JlZW5fY291bnQgPSAwXFxud2FybV9jb3VudCA9IDBcXG50b3RhbCA9IDBcXG5cXG5mb3IgaSBpbiByYW5nZSgwLCBsZW4ocGl4ZWxzKSwgNCk6XFxuICAgIHIsIGcsIGIgPSBwaXhlbHNbaV0sIHBpeGVsc1tpKzFdLCBwaXhlbHNbaSsyXVxcbiAgICB0b3RhbCArPSAxXFxuICAgIGJyaWdodG5lc3MgPSAociArIGcgKyBiKSAvIDNcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgZWxpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgIGVsaWYgciA+IDAuMiBhbmQgZyA+IDAuMTUgYW5kIHIgPiBiICogMS4zOlxcbiAgICAgICAgd2FybV9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJSZWQ6IHsxMDAqcmVkX2NvdW50L3RvdGFsOi4xZn0lLCBHcmVlbjogezEwMCpncmVlbl9jb3VudC90b3RhbDouMWZ9JSwgV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIHNwZWNpZmljYWxseVxcbnJpZ2h0X2cgPSAwXFxucmlnaHRfdCA9IDBcXG5mb3IgeSBpbiByYW5nZShoKTpcXG4gICAgZm9yIHggaW4gcmFuZ2UoaW50KHcqMC43KSwgdywgMyk6XFxuICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICByLCBnLCBiID0gcGl4ZWxzW2lkeF0sIHBpeGVsc1tpZHgrMV0sIHBpeGVsc1tpZHgrMl1cXG4gICAgICAgICAgICByaWdodF90ICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4wOCBhbmQgZyA+IHIgKiAxLjE1IGFuZCBnID4gYiAqIDEuMTU6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2cgKz0gMVxcbnByaW50KGZcXFwiUmlnaHQgc2lkZSBncmVlbjogezEwMCpyaWdodF9nL3JpZ2h0X3Q6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkOiAxNC4wJSwgR3JlZW46IDMuOCUsIFdhcm06IDMxLjQlXFxuUmlnaHQgc2lkZSBncmVlbjogMTAuOCVcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kIC0gZ3JlZW4gaXMgbm93IHZpc2libGUgb24gdGhlIHJpZ2h0IHNpZGUuIFRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgd2l0aCByZWQgb24gdGhlIGxlZnQsIGdyZWVuIG9uIHRoZSByaWdodCAoQ29ybmVsbCBib3ggcGFsZXR0ZSksIHdhcm0gbGlnaHQsIGFuZCBkYXJrIHNoYWRvd3MuIExldCBtZSBub3cgYWRkIHNvbWUgZmluYWwgcG9saXNoOiBhIGNhbmRsZXN0aWNrIGFzIGFuIGFkZGl0aW9uYWwgY2xhc3NpY2FsIHByb3AgKHdoaWNoIGFsc28ganVzdGlmaWVzIHRoZSB3YXJtIGxpZ2h0IHNvdXJjZSksIGFuZCBtYWtlIGFkanVzdG1lbnRzIHRvIHRoZSBTdXphbm5lIGJ1c3QgcG9zaXRpb25pbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk5Y2VkODg0NWIxOWNmNTciLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ0FORExFU1RJQ0sgd2l0aCBjYW5kbGUgLSBhZGRpdGlvbmFsIGNsYXNzaWNhbCBwcm9wXFxuIyBKdXN0aWZpZXMgdGhlIHdhcm0gbGlnaHQgc291cmNlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQ2FuZGxlc3RpY2tNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSBjYW5kbGVzdGljayAocmFkaXVzLCBoZWlnaHQpIOKAlCBsYXRoZWRcXG5zdGlja19wcm9maWxlID0gW1xcbiAgICAoMC4wMCwgMC4wMCksICAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4xMiwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjEzLCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMiwgMC4wMyksICAgICMgXFxuICAgICgwLjA4LCAwLjA0KSwgICAgIyBiYXNlIHRvIHN0ZW1cXG4gICAgKDAuMDUsIDAuMDYpLCAgICAjIHN0ZW0gYmFzZVxcbiAgICAoMC4wNCwgMC4xNSksICAgICMgc3RlbVxcbiAgICAoMC4wNCwgMC4yNSksICAgICMgc3RlbVxcbiAgICAoMC4wNSwgMC4zMCksICAgICMgbWlkIGRlY29yYXRpdmVcXG4gICAgKDAuMDQsIDAuMzUpLCAgICAjIFxcbiAgICAoMC4wMzUsIDAuNDApLCAgICMgdXBwZXIgc3RlbVxcbiAgICAoMC4wNSwgMC40NCksICAgICMgY2FuZGxlIGN1cCBiYXNlXFxuICAgICgwLjA2LCAwLjQ2KSwgICAgIyBjdXBcXG4gICAgKDAuMDU1LCAwLjQ4KSwgICAjIGN1cCBsaXBcXG4gICAgKDAuMDQsIDAuNTApLCAgICAjIGN1cCBpbm5lclxcbiAgICAoMC4wMCwgMC41MCksICAgICMgY2VudGVyIHRvcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBzdGlja19wcm9maWxlOlxcbiAgICByaW5nID0gW11cXG4gICAgaWYgciA8IDAuMDAxOlxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4oYWxsX3ZlcnRzKSAtIDEpOlxcbiAgICByaW5nX2EgPSBhbGxfdmVydHNbcmldXFxuICAgIHJpbmdfYiA9IGFsbF92ZXJ0c1tyaSArIDFdXFxuICAgIHJhLCBfID0gc3RpY2tfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBzdGlja19wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuc3RpY2tfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkNhbmRsZXN0aWNrXFxcIiwgbWVzaClcXG5saW5rX29iaihzdGlja19vYmopXFxuc3RpY2tfb2JqLmxvY2F0aW9uID0gKC0xLjYsIDAuOCwgMC4wKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBzdGlja19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IHN0aWNrX29iai5tb2RpZmllcnMubmV3KFxcXCJTdWJzdXJmXFxcIiwgJ1NVQlNVUkYnKVxcbm1vZC5sZXZlbHMgPSAxXFxubW9kLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuIyBDYW5kbGVcXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX2N5bGluZGVyX2FkZChyYWRpdXM9MC4wMzUsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgtMS42LCAwLjgsIDAuNTc1KSlcXG5jYW5kbGUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuY2FuZGxlLm5hbWUgPSBcXFwiQ2FuZGxlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBDYW5kbGUgZmxhbWUgLSBhIHNtYWxsIGVtaXNzaXZlIHNoYXBlXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz0wLjAzLCBzZWdtZW50cz0xNiwgcmluZ19jb3VudD04LCBsb2NhdGlvbj0oLTEuNiwgMC44LCAwLjcwKSlcXG5mbGFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5mbGFtZS5uYW1lID0gXFxcIkNhbmRsZUZsYW1lXFxcIlxcbmZsYW1lLnNjYWxlID0gKDAuNiwgMC42LCAxLjgpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1GYWxzZSwgc2NhbGU9VHJ1ZSlcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbnByaW50KFxcXCJDYW5kbGVzdGljayB3aXRoIGNhbmRsZSBhbmQgZmxhbWUgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNhbmRsZXN0aWNrXFxcIjogc3RpY2tfb2JqLm5hbWUsIFxcXCJjYW5kbGVcXFwiOiBjYW5kbGUubmFtZSwgXFxcImZsYW1lXFxcIjogZmxhbWUubmFtZX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05OWNlZDg4NDViMTljZjU3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjYW5kbGVzdGlja1wiOiBcIkNhbmRsZXN0aWNrXCIsXG4gICAgXCJjYW5kbGVcIjogXCJDYW5kbGVcIixcbiAgICBcImZsYW1lXCI6IFwiQ2FuZGxlRmxhbWVcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbmRsZXN0aWNrIHdpdGggY2FuZGxlIGFuZCBmbGFtZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NjI1MzczM2JiMDYwZDViIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIENhbmRsZXN0aWNrOiBBZ2VkIGJyYXNzL2Jyb256ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZXN0aWNrQnJhc3NcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDIsIDAuMjAsIDEuMCkgICMgYnJhc3NcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjM1XFxuXFxuIyBQYXRpbmEgdmFyaWF0aW9uXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNS4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MiwgMC4yMCwgMS4wKSAgIyBicmFzc1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjM1LCAwLjIwLCAxLjApICAjIHBhdGluYVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkNhbmRsZXN0aWNrXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGU6IFdheGVkIG9mZi13aGl0ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MiwgMC43MiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGUgZmxhbWU6IEVtaXNzaXZlIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQ2FuZGxlRmxhbWVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuZW1pc3Npb24gPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVFbWlzc2lvbicsICgyMDAsIDApKVxcbmVtaXNzaW9uLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDEuMCwgMC43LCAwLjMsIDEuMCkgICMgd2FybSBmbGFtZVxcbmVtaXNzaW9uLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm50LmxpbmtzLm5ldyhlbWlzc2lvbi5vdXRwdXRzWydFbWlzc2lvbiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlRmxhbWVcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgQWRkIGEgcG9pbnQgbGlnaHQgYXQgdGhlIGZsYW1lIGZvciBhY3R1YWwgaWxsdW1pbmF0aW9uXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J1BPSU5UJywgbG9jYXRpb249KC0xLjYsIDAuOCwgMC43MikpXFxuZmxhbWVfbGlnaHQgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxhbWVfbGlnaHQubmFtZSA9IFxcXCJDYW5kbGVMaWdodFxcXCJcXG5mbGFtZV9saWdodC5kYXRhLmVuZXJneSA9IDUwXFxuZmxhbWVfbGlnaHQuZGF0YS5jb2xvciA9ICgxLjAsIDAuNywgMC4zKVxcbmZsYW1lX2xpZ2h0LmRhdGEuc2hhZG93X3NvZnRfc2l6ZSA9IDAuMDVcXG5cXG5wcmludChcXFwiQ2FuZGxlc3RpY2ssIGNhbmRsZSwgYW5kIGZsYW1lIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2MjUzNzMzYmIwNjBkNWIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJDYW5kbGVzdGljaywgY2FuZGxlLCBhbmQgZmxhbWUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:19:44 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301581-ERjjXW2L6gwikKjaz2dt", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca39ef9d04eca7-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301581-ERjjXW2L6gwikKjaz2dt\",\"object\":\"chat.completion\",\"created\":1784301581,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-ad276f7e043b8f86\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render with candle\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview8.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview8.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":51738,\"completion_tokens\":424,\"total_tokens\":52162,\"cost\":0.01099937688,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":50752,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.01099937688,\"upstream_inference_prompt_cost\":0.00975129048,\"upstream_inference_completions_cost\":0.0012480864},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDE1ODEtRVJqalhXMkw2Z3dpa0tqYXoyZHQiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAxNTgxLCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYWQyNzZmN2UwNDNiOGY4NiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBSZW5kZXIgd2l0aCBjYW5kbGVcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3OC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc4LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDEweDEwIGdyaWQpOlxcXCIpXFxuZm9yIGd5IGluIHJhbmdlKDEwKTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDEwKTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDEwXFxuICAgICAgICB4MiA9IChneCsxKSAqIHcgLy8gMTBcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDEwXFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gMTBcXG4gICAgICAgIGJyaWdodF9zdW0gPSAwXFxuICAgICAgICBjb3VudCA9IDBcXG4gICAgICAgIGZvciB5IGluIHJhbmdlKHkxLCB5MiwgMjUpOlxcbiAgICAgICAgICAgIGZvciB4IGluIHJhbmdlKHgxLCB4MiwgMjUpOlxcbiAgICAgICAgICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgICAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgICAgICAgICAgYnJpZ2h0X3N1bSArPSAocGl4ZWxzW2lkeF0gKyBwaXhlbHNbaWR4KzFdICsgcGl4ZWxzW2lkeCsyXSkgLyAzXFxuICAgICAgICAgICAgICAgICAgICBjb3VudCArPSAxXFxuICAgICAgICBicmlnaHQgPSBicmlnaHRfc3VtIC8gY291bnQgaWYgY291bnQgPiAwIGVsc2UgMFxcbiAgICAgICAgaWYgYnJpZ2h0IDwgMC4wNjogcm93ICs9IFxcXCIgIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4xMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40OiByb3cgKz0gXFxcIuKXjyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNTU6IHJvdyArPSBcXFwi4paTIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC43OiByb3cgKz0gXFxcIuKWkiBcXFwiXFxuICAgICAgICBlbHNlOiByb3cgKz0gXFxcIuKWiCBcXFwiXFxuICAgIHByaW50KGZcXFwiICBSb3cge2d5fTogfHtyb3d9fFxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjUxNzM4LCJjb21wbGV0aW9uX3Rva2VucyI6NDI0LCJ0b3RhbF90b2tlbnMiOjUyMTYyLCJjb3N0IjowLjAxMDk5OTM3Njg4LCJpc19ieW9rIjpmYWxzZSwicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjp7ImNhY2hlZF90b2tlbnMiOjUwNzUyLCJjYWNoZV93cml0ZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwidmlkZW9fdG9rZW5zIjowfSwiY29zdF9kZXRhaWxzIjp7InVwc3RyZWFtX2luZmVyZW5jZV9jb3N0IjowLjAxMDk5OTM3Njg4LCJ1cHN0cmVhbV9pbmZlcmVuY2VfcHJvbXB0X2Nvc3QiOjAuMDA5NzUxMjkwNDgsInVwc3RyZWFtX2luZmVyZW5jZV9jb21wbGV0aW9uc19jb3N0IjowLjAwMTI0ODA4NjR9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImltYWdlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfX19"}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-ad276f7e043b8f86", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Render with candle\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview8.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview8.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (10x10 grid):\")\nfor gy in range(10):\n    row = \"\"\n    for gx in range(10):\n        x1 = gx * w // 10\n        x2 = (gx+1) * w // 10\n        y1 = gy * h // 10\n        y2 = (gy+1) * h // 10\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 25):\n            for x in range(x1, x2, 25):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render with candle\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview8.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview8.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 51738, "tokens_out": 424, "cost_usd": 0.01099937688, "cached_tokens": 50752}, "error": null}
{"ts": "2026-07-17T15:19:52.872211+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-ad276f7e043b8f86", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Render with candle\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview8.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview8.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (10x10 grid):\")\nfor gy in range(10):\n    row = \"\"\n    for gx in range(10):\n        x1 = gx * w // 10\n        x2 = (gx+1) * w // 10\n        y1 = gy * h // 10\n        y2 = (gy+1) * h // 10\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 25):\n            for x in range(x1, x2, 25):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render with candle\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview8.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview8.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:19:52.872211+00:00", "type": "tool_call", "id": "chatcmpl-tool-ad276f7e043b8f86", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Render with candle\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview8.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview8.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (10x10 grid):\")\nfor gy in range(10):\n    row = \"\"\n    for gx in range(10):\n        x1 = gx * w // 10\n        x2 = (gx+1) * w // 10\n        y1 = gy * h // 10\n        y2 = (gy+1) * h // 10\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 25):\n            for x in range(x1, x2, 25):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render with candle\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview8.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview8.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:20:22.763272+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-ad276f7e043b8f86", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▓ ● ·             |\\n  Row 4: |▒ ▒ ▓ ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ ▒ ▓ ▓ ○ •   |\\n  Row 7: |● █ █ █ ▒ ▒ ▒ ▒ ▓ ▓ |\\n  Row 8: |█ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 9: |▒ █ █ █ █ █ █ ▒ ▒ ▓ |\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:20:27.280207+00:00", "type": "llm_call", "call_index": 67, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:20:22.766281+00:00", "finished_at": "2026-07-17T15:20:27.280207+00:00", "duration_s": 4.51500000001397, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}"}, {"role": "assistant", "content": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a1bde82900051568", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▒ ● ·             |\\n  Row 4: |█ ▒ ● ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8bf5081c37eebeb6", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8bf5081c37eebeb6", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-96f3c02259f22638", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check the right side of the image for green\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed color check on the right portion\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    if brightness < 0.05:\\n        continue\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check the right side specifically\\nright_g = 0\\nright_t = 0\\nfor y in range(h):\\n    for x in range(int(w*0.7), w, 3):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_t += 1\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\n                right_g += 1\\nprint(f\\\"Right side green: {100*right_g/right_t:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-96f3c02259f22638", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\nRight side green: 10.8%\\n\"\n}"}, {"role": "assistant", "content": "Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.", "tool_calls": [{"id": "chatcmpl-tool-99ced8845b19cf57", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# CANDLESTICK with candle - additional classical prop\\n# Justifies the warm light source\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"CandlestickMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the candlestick (radius, height) — lathed\\nstick_profile = [\\n    (0.00, 0.00),    # center bottom\\n    (0.12, 0.00),    # base edge\\n    (0.13, 0.01),    # base lip\\n    (0.12, 0.03),    # \\n    (0.08, 0.04),    # base to stem\\n    (0.05, 0.06),    # stem base\\n    (0.04, 0.15),    # stem\\n    (0.04, 0.25),    # stem\\n    (0.05, 0.30),    # mid decorative\\n    (0.04, 0.35),    # \\n    (0.035, 0.40),   # upper stem\\n    (0.05, 0.44),    # candle cup base\\n    (0.06, 0.46),    # cup\\n    (0.055, 0.48),   # cup lip\\n    (0.04, 0.50),    # cup inner\\n    (0.00, 0.50),    # center top\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in stick_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = stick_profile[ri]\\n    rb, _ = stick_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nstick_obj = bpy.data.objects.new(\\\"Candlestick\\\", mesh)\\nlink_obj(stick_obj)\\nstick_obj.location = (-1.6, 0.8, 0.0)\\nbpy.context.view_layer.objects.active = stick_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = stick_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# Candle\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\ncandle = bpy.context.active_object\\ncandle.name = \\\"Candle\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Candle flame - a small emissive shape\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\nflame = bpy.context.active_object\\nflame.name = \\\"CandleFlame\\\"\\nflame.scale = (0.6, 0.6, 1.8)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\nbpy.ops.object.shade_smooth()\\n\\nprint(\\\"Candlestick with candle and flame built.\\\")\\nresult = {\\\"candlestick\\\": stick_obj.name, \\\"candle\\\": candle.name, \\\"flame\\\": flame.name}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-99ced8845b19cf57", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"candlestick\": \"Candlestick\",\n    \"candle\": \"Candle\",\n    \"flame\": \"CandleFlame\"\n  },\n  \"stdout\": \"Candlestick with candle and flame built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-86253733bb060d5b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- Candlestick: Aged brass/bronze ---\\nmat, nt = create_material(\\\"M_CandlestickBrass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 5.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 40.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Candlestick\\\"].data.materials.append(mat)\\n\\n# --- Candle: Waxed off-white ---\\nmat, nt = create_material(\\\"M_Candle\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.5\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Candle\\\"].data.materials.append(mat)\\n\\n# --- Candle flame: Emissive ---\\nmat, nt = create_material(\\\"M_CandleFlame\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\nemission.inputs['Strength'].default_value = 15.0\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\nbpy.data.objects[\\\"CandleFlame\\\"].data.materials.append(mat)\\n\\n# Add a point light at the flame for actual illumination\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\nflame_light = bpy.context.active_object\\nflame_light.name = \\\"CandleLight\\\"\\nflame_light.data.energy = 50\\nflame_light.data.color = (1.0, 0.7, 0.3)\\nflame_light.data.shadow_soft_size = 0.05\\n\\nprint(\\\"Candlestick, candle, and flame materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-86253733bb060d5b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Candlestick, candle, and flame materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad276f7e043b8f86", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render with candle\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview8.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview8.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad276f7e043b8f86", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▓ ● ·             |\\n  Row 4: |▒ ▒ ▓ ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ ▒ ▓ ▓ ○ •   |\\n  Row 7: |● █ █ █ ▒ ▒ ▒ ▒ ▓ ▓ |\\n  Row 8: |█ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 9: |▒ █ █ █ █ █ █ ▒ ▒ ▓ |\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:20:22.766281+00:00", "finished_at": "2026-07-17T15:20:27.279205+00:00", "duration_s": 4.51500000001397, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "196511", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9cddced158a16a7f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Connected bump to BSDF Normal\\\\nConnected BSDF to output\\\\n\\\\nFinal links:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n  Bump.Normal -> Principled BSDF.Normal\\\\n  Principled BSDF.BSDF -> Material Output.Surface\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good, Suzanne material is fixed. Now let me render to check everything looks good.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a1bde82900051568\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a1bde82900051568\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▒ ● ·             |\\\\n  Row 4: |█ ▒ ● ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-96f3c02259f22638\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check the right side of the image for green\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed color check on the right portion\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    if brightness < 0.05:\\\\n        continue\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check the right side specifically\\\\nright_g = 0\\\\nright_t = 0\\\\nfor y in range(h):\\\\n    for x in range(int(w*0.7), w, 3):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_t += 1\\\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\\\n                right_g += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_g/right_t:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-96f3c02259f22638\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\\\nRight side green: 10.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-99ced8845b19cf57\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# CANDLESTICK with candle - additional classical prop\\\\n# Justifies the warm light source\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"CandlestickMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the candlestick (radius, height) — lathed\\\\nstick_profile = [\\\\n    (0.00, 0.00),    # center bottom\\\\n    (0.12, 0.00),    # base edge\\\\n    (0.13, 0.01),    # base lip\\\\n    (0.12, 0.03),    # \\\\n    (0.08, 0.04),    # base to stem\\\\n    (0.05, 0.06),    # stem base\\\\n    (0.04, 0.15),    # stem\\\\n    (0.04, 0.25),    # stem\\\\n    (0.05, 0.30),    # mid decorative\\\\n    (0.04, 0.35),    # \\\\n    (0.035, 0.40),   # upper stem\\\\n    (0.05, 0.44),    # candle cup base\\\\n    (0.06, 0.46),    # cup\\\\n    (0.055, 0.48),   # cup lip\\\\n    (0.04, 0.50),    # cup inner\\\\n    (0.00, 0.50),    # center top\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in stick_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = stick_profile[ri]\\\\n    rb, _ = stick_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nstick_obj = bpy.data.objects.new(\\\\\\\"Candlestick\\\\\\\", mesh)\\\\nlink_obj(stick_obj)\\\\nstick_obj.location = (-1.6, 0.8, 0.0)\\\\nbpy.context.view_layer.objects.active = stick_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = stick_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# Candle\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\\\ncandle = bpy.context.active_object\\\\ncandle.name = \\\\\\\"Candle\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Candle flame - a small emissive shape\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\\\nflame = bpy.context.active_object\\\\nflame.name = \\\\\\\"CandleFlame\\\\\\\"\\\\nflame.scale = (0.6, 0.6, 1.8)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nprint(\\\\\\\"Candlestick with candle and flame built.\\\\\\\")\\\\nresult = {\\\\\\\"candlestick\\\\\\\": stick_obj.name, \\\\\\\"candle\\\\\\\": candle.name, \\\\\\\"flame\\\\\\\": flame.name}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-99ced8845b19cf57\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"candlestick\\\": \\\"Candlestick\\\",\\n    \\\"candle\\\": \\\"Candle\\\",\\n    \\\"flame\\\": \\\"CandleFlame\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick with candle and flame built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-86253733bb060d5b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- Candlestick: Aged brass/bronze ---\\\\nmat, nt = create_material(\\\\\\\"M_CandlestickBrass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 5.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 40.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Candlestick\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle: Waxed off-white ---\\\\nmat, nt = create_material(\\\\\\\"M_Candle\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.5\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Candle\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle flame: Emissive ---\\\\nmat, nt = create_material(\\\\\\\"M_CandleFlame\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\\\nemission.inputs['Strength'].default_value = 15.0\\\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"CandleFlame\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Add a point light at the flame for actual illumination\\\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\\\nflame_light = bpy.context.active_object\\\\nflame_light.name = \\\\\\\"CandleLight\\\\\\\"\\\\nflame_light.data.energy = 50\\\\nflame_light.data.color = (1.0, 0.7, 0.3)\\\\nflame_light.data.shadow_soft_size = 0.05\\\\n\\\\nprint(\\\\\\\"Candlestick, candle, and flame materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-86253733bb060d5b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick, candle, and flame materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad276f7e043b8f86\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render with candle\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview8.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview8.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad276f7e043b8f86\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▓ ● ·             |\\\\n  Row 4: |▒ ▒ ▓ ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ ▒ ▓ ▓ ○ •   |\\\\n  Row 7: |● █ █ █ ▒ ▒ ▒ ▒ ▓ ▓ |\\\\n  Row 8: |█ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 9: |▒ █ █ █ █ █ █ ▒ ▒ ▓ |\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWNkZGNlZDE1OGExNmE3ZiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBDb25uZWN0IGJ1bXAgdG8gQlNERiBOb3JtYWwgYW5kIEJTREYgdG8gb3V0cHV0XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5cXG4jIE1ha2Ugc3VyZSBidW1wIG5vcm1hbCBnb2VzIHRvIEJTREZcXG5idW1wID0gTm9uZVxcbmJzZGYgPSBOb25lXFxub3V0cHV0ID0gTm9uZVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ0JVTVAnOlxcbiAgICAgICAgYnVtcCA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ0JTREZfUFJJTkNJUExFRCc6XFxuICAgICAgICBic2RmID0gbm9kZVxcbiAgICBlbGlmIG5vZGUudHlwZSA9PSAnT1VUUFVUX01BVEVSSUFMJzpcXG4gICAgICAgIG91dHB1dCA9IG5vZGVcXG5cXG5pZiBidW1wIGFuZCBic2RmOlxcbiAgICBudC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXFwiKVxcblxcbmlmIGJzZGYgYW5kIG91dHB1dDpcXG4gICAgbnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuICAgIHByaW50KFxcXCJDb25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXFwiKVxcblxcbnByaW50KFxcXCJcXFxcbkZpbmFsIGxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05Y2RkY2VkMTU4YTE2YTdmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXG5Db25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXG5cXG5GaW5hbCBsaW5rczpcXG4gIFRleHR1cmUgQ29vcmRpbmF0ZS5HZW5lcmF0ZWQgLT4gTWFwcGluZy5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IE5vaXNlIFRleHR1cmUuVmVjdG9yXFxuICBNYXBwaW5nLlZlY3RvciAtPiBXYXZlIFRleHR1cmUuVmVjdG9yXFxuICBXYXZlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkFcXG4gIE5vaXNlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkJcXG4gIE1peC5SZXN1bHQgLT4gQ29sb3IgUmFtcC5GYWN0b3JcXG4gIENvbG9yIFJhbXAuQ29sb3IgLT4gUHJpbmNpcGxlZCBCU0RGLkJhc2UgQ29sb3JcXG4gIE5vaXNlIFRleHR1cmUuMDAxLkZhY3RvciAtPiBCdW1wLkhlaWdodFxcbiAgQnVtcC5Ob3JtYWwgLT4gUHJpbmNpcGxlZCBCU0RGLk5vcm1hbFxcbiAgUHJpbmNpcGxlZCBCU0RGLkJTREYgLT4gTWF0ZXJpYWwgT3V0cHV0LlN1cmZhY2VcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kLCBTdXphbm5lIG1hdGVyaWFsIGlzIGZpeGVkLiBOb3cgbGV0IG1lIHJlbmRlciB0byBjaGVjayBldmVyeXRoaW5nIGxvb2tzIGdvb2QuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWExYmRlODI5MDAwNTE1NjgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc3LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTFiZGU4MjkwMDA1MTU2OCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8ICDCtyDCtyAgICAgICAgIMK3IMK3IMK3IHxcXG4gIFJvdyAxOiB84oCiIMK3ICAgICDCtyDigKIg4oCiIMK3IMK3ICAgfFxcbiAgUm93IDI6IHzCtyDigKIg4peLIOKAoiDCtyAgICAgICAgICAgfFxcbiAgUm93IDM6IHzilpMg4paSIOKXjyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNDogfOKWiCDilpIg4pePIMK3ICAgICAgICAgICAgIHxcXG4gIFJvdyA1OiB84paTIOKXjyDilpMg4pePIOKXjyDCtyAgICAgICAgIHxcXG4gIFJvdyA2OiB8ICDil48g4paSIOKWkiDilogg4paSIOKWkyDil4sg4oCiICAgfFxcbiAgUm93IDc6IHzil4sg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDg6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paSIOKWkiDilpIgfFxcbiAgUm93IDk6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLThiZjUwODFjMzdlZWJlYjYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04YmY1MDgxYzM3ZWViZWI2IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIG9mIHRoZSBpbWFnZSBmb3IgZ3JlZW5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgRGV0YWlsZWQgY29sb3IgY2hlY2sgb24gdGhlIHJpZ2h0IHBvcnRpb25cXG5yZWRfY291bnQgPSAwXFxuZ3JlZW5fY291bnQgPSAwXFxud2FybV9jb3VudCA9IDBcXG50b3RhbCA9IDBcXG5cXG5mb3IgaSBpbiByYW5nZSgwLCBsZW4ocGl4ZWxzKSwgNCk6XFxuICAgIHIsIGcsIGIgPSBwaXhlbHNbaV0sIHBpeGVsc1tpKzFdLCBwaXhlbHNbaSsyXVxcbiAgICB0b3RhbCArPSAxXFxuICAgIGJyaWdodG5lc3MgPSAociArIGcgKyBiKSAvIDNcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgZWxpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgIGVsaWYgciA+IDAuMiBhbmQgZyA+IDAuMTUgYW5kIHIgPiBiICogMS4zOlxcbiAgICAgICAgd2FybV9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJSZWQ6IHsxMDAqcmVkX2NvdW50L3RvdGFsOi4xZn0lLCBHcmVlbjogezEwMCpncmVlbl9jb3VudC90b3RhbDouMWZ9JSwgV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIHNwZWNpZmljYWxseVxcbnJpZ2h0X2cgPSAwXFxucmlnaHRfdCA9IDBcXG5mb3IgeSBpbiByYW5nZShoKTpcXG4gICAgZm9yIHggaW4gcmFuZ2UoaW50KHcqMC43KSwgdywgMyk6XFxuICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICByLCBnLCBiID0gcGl4ZWxzW2lkeF0sIHBpeGVsc1tpZHgrMV0sIHBpeGVsc1tpZHgrMl1cXG4gICAgICAgICAgICByaWdodF90ICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4wOCBhbmQgZyA+IHIgKiAxLjE1IGFuZCBnID4gYiAqIDEuMTU6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2cgKz0gMVxcbnByaW50KGZcXFwiUmlnaHQgc2lkZSBncmVlbjogezEwMCpyaWdodF9nL3JpZ2h0X3Q6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkOiAxNC4wJSwgR3JlZW46IDMuOCUsIFdhcm06IDMxLjQlXFxuUmlnaHQgc2lkZSBncmVlbjogMTAuOCVcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kIC0gZ3JlZW4gaXMgbm93IHZpc2libGUgb24gdGhlIHJpZ2h0IHNpZGUuIFRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgd2l0aCByZWQgb24gdGhlIGxlZnQsIGdyZWVuIG9uIHRoZSByaWdodCAoQ29ybmVsbCBib3ggcGFsZXR0ZSksIHdhcm0gbGlnaHQsIGFuZCBkYXJrIHNoYWRvd3MuIExldCBtZSBub3cgYWRkIHNvbWUgZmluYWwgcG9saXNoOiBhIGNhbmRsZXN0aWNrIGFzIGFuIGFkZGl0aW9uYWwgY2xhc3NpY2FsIHByb3AgKHdoaWNoIGFsc28ganVzdGlmaWVzIHRoZSB3YXJtIGxpZ2h0IHNvdXJjZSksIGFuZCBtYWtlIGFkanVzdG1lbnRzIHRvIHRoZSBTdXphbm5lIGJ1c3QgcG9zaXRpb25pbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk5Y2VkODg0NWIxOWNmNTciLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ0FORExFU1RJQ0sgd2l0aCBjYW5kbGUgLSBhZGRpdGlvbmFsIGNsYXNzaWNhbCBwcm9wXFxuIyBKdXN0aWZpZXMgdGhlIHdhcm0gbGlnaHQgc291cmNlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQ2FuZGxlc3RpY2tNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSBjYW5kbGVzdGljayAocmFkaXVzLCBoZWlnaHQpIOKAlCBsYXRoZWRcXG5zdGlja19wcm9maWxlID0gW1xcbiAgICAoMC4wMCwgMC4wMCksICAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4xMiwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjEzLCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMiwgMC4wMyksICAgICMgXFxuICAgICgwLjA4LCAwLjA0KSwgICAgIyBiYXNlIHRvIHN0ZW1cXG4gICAgKDAuMDUsIDAuMDYpLCAgICAjIHN0ZW0gYmFzZVxcbiAgICAoMC4wNCwgMC4xNSksICAgICMgc3RlbVxcbiAgICAoMC4wNCwgMC4yNSksICAgICMgc3RlbVxcbiAgICAoMC4wNSwgMC4zMCksICAgICMgbWlkIGRlY29yYXRpdmVcXG4gICAgKDAuMDQsIDAuMzUpLCAgICAjIFxcbiAgICAoMC4wMzUsIDAuNDApLCAgICMgdXBwZXIgc3RlbVxcbiAgICAoMC4wNSwgMC40NCksICAgICMgY2FuZGxlIGN1cCBiYXNlXFxuICAgICgwLjA2LCAwLjQ2KSwgICAgIyBjdXBcXG4gICAgKDAuMDU1LCAwLjQ4KSwgICAjIGN1cCBsaXBcXG4gICAgKDAuMDQsIDAuNTApLCAgICAjIGN1cCBpbm5lclxcbiAgICAoMC4wMCwgMC41MCksICAgICMgY2VudGVyIHRvcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBzdGlja19wcm9maWxlOlxcbiAgICByaW5nID0gW11cXG4gICAgaWYgciA8IDAuMDAxOlxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4oYWxsX3ZlcnRzKSAtIDEpOlxcbiAgICByaW5nX2EgPSBhbGxfdmVydHNbcmldXFxuICAgIHJpbmdfYiA9IGFsbF92ZXJ0c1tyaSArIDFdXFxuICAgIHJhLCBfID0gc3RpY2tfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBzdGlja19wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuc3RpY2tfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkNhbmRsZXN0aWNrXFxcIiwgbWVzaClcXG5saW5rX29iaihzdGlja19vYmopXFxuc3RpY2tfb2JqLmxvY2F0aW9uID0gKC0xLjYsIDAuOCwgMC4wKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBzdGlja19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IHN0aWNrX29iai5tb2RpZmllcnMubmV3KFxcXCJTdWJzdXJmXFxcIiwgJ1NVQlNVUkYnKVxcbm1vZC5sZXZlbHMgPSAxXFxubW9kLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuIyBDYW5kbGVcXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX2N5bGluZGVyX2FkZChyYWRpdXM9MC4wMzUsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgtMS42LCAwLjgsIDAuNTc1KSlcXG5jYW5kbGUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuY2FuZGxlLm5hbWUgPSBcXFwiQ2FuZGxlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBDYW5kbGUgZmxhbWUgLSBhIHNtYWxsIGVtaXNzaXZlIHNoYXBlXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz0wLjAzLCBzZWdtZW50cz0xNiwgcmluZ19jb3VudD04LCBsb2NhdGlvbj0oLTEuNiwgMC44LCAwLjcwKSlcXG5mbGFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5mbGFtZS5uYW1lID0gXFxcIkNhbmRsZUZsYW1lXFxcIlxcbmZsYW1lLnNjYWxlID0gKDAuNiwgMC42LCAxLjgpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1GYWxzZSwgc2NhbGU9VHJ1ZSlcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbnByaW50KFxcXCJDYW5kbGVzdGljayB3aXRoIGNhbmRsZSBhbmQgZmxhbWUgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNhbmRsZXN0aWNrXFxcIjogc3RpY2tfb2JqLm5hbWUsIFxcXCJjYW5kbGVcXFwiOiBjYW5kbGUubmFtZSwgXFxcImZsYW1lXFxcIjogZmxhbWUubmFtZX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05OWNlZDg4NDViMTljZjU3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjYW5kbGVzdGlja1wiOiBcIkNhbmRsZXN0aWNrXCIsXG4gICAgXCJjYW5kbGVcIjogXCJDYW5kbGVcIixcbiAgICBcImZsYW1lXCI6IFwiQ2FuZGxlRmxhbWVcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbmRsZXN0aWNrIHdpdGggY2FuZGxlIGFuZCBmbGFtZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NjI1MzczM2JiMDYwZDViIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIENhbmRsZXN0aWNrOiBBZ2VkIGJyYXNzL2Jyb256ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZXN0aWNrQnJhc3NcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDIsIDAuMjAsIDEuMCkgICMgYnJhc3NcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjM1XFxuXFxuIyBQYXRpbmEgdmFyaWF0aW9uXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNS4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MiwgMC4yMCwgMS4wKSAgIyBicmFzc1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjM1LCAwLjIwLCAxLjApICAjIHBhdGluYVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkNhbmRsZXN0aWNrXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGU6IFdheGVkIG9mZi13aGl0ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MiwgMC43MiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGUgZmxhbWU6IEVtaXNzaXZlIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQ2FuZGxlRmxhbWVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuZW1pc3Npb24gPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVFbWlzc2lvbicsICgyMDAsIDApKVxcbmVtaXNzaW9uLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDEuMCwgMC43LCAwLjMsIDEuMCkgICMgd2FybSBmbGFtZVxcbmVtaXNzaW9uLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm50LmxpbmtzLm5ldyhlbWlzc2lvbi5vdXRwdXRzWydFbWlzc2lvbiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlRmxhbWVcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgQWRkIGEgcG9pbnQgbGlnaHQgYXQgdGhlIGZsYW1lIGZvciBhY3R1YWwgaWxsdW1pbmF0aW9uXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J1BPSU5UJywgbG9jYXRpb249KC0xLjYsIDAuOCwgMC43MikpXFxuZmxhbWVfbGlnaHQgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxhbWVfbGlnaHQubmFtZSA9IFxcXCJDYW5kbGVMaWdodFxcXCJcXG5mbGFtZV9saWdodC5kYXRhLmVuZXJneSA9IDUwXFxuZmxhbWVfbGlnaHQuZGF0YS5jb2xvciA9ICgxLjAsIDAuNywgMC4zKVxcbmZsYW1lX2xpZ2h0LmRhdGEuc2hhZG93X3NvZnRfc2l6ZSA9IDAuMDVcXG5cXG5wcmludChcXFwiQ2FuZGxlc3RpY2ssIGNhbmRsZSwgYW5kIGZsYW1lIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2MjUzNzMzYmIwNjBkNWIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJDYW5kbGVzdGljaywgY2FuZGxlLCBhbmQgZmxhbWUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWQyNzZmN2UwNDNiOGY4NiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBSZW5kZXIgd2l0aCBjYW5kbGVcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3OC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc4LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDEweDEwIGdyaWQpOlxcXCIpXFxuZm9yIGd5IGluIHJhbmdlKDEwKTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDEwKTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDEwXFxuICAgICAgICB4MiA9IChneCsxKSAqIHcgLy8gMTBcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDEwXFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gMTBcXG4gICAgICAgIGJyaWdodF9zdW0gPSAwXFxuICAgICAgICBjb3VudCA9IDBcXG4gICAgICAgIGZvciB5IGluIHJhbmdlKHkxLCB5MiwgMjUpOlxcbiAgICAgICAgICAgIGZvciB4IGluIHJhbmdlKHgxLCB4MiwgMjUpOlxcbiAgICAgICAgICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgICAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgICAgICAgICAgYnJpZ2h0X3N1bSArPSAocGl4ZWxzW2lkeF0gKyBwaXhlbHNbaWR4KzFdICsgcGl4ZWxzW2lkeCsyXSkgLyAzXFxuICAgICAgICAgICAgICAgICAgICBjb3VudCArPSAxXFxuICAgICAgICBicmlnaHQgPSBicmlnaHRfc3VtIC8gY291bnQgaWYgY291bnQgPiAwIGVsc2UgMFxcbiAgICAgICAgaWYgYnJpZ2h0IDwgMC4wNjogcm93ICs9IFxcXCIgIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4xMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40OiByb3cgKz0gXFxcIuKXjyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNTU6IHJvdyArPSBcXFwi4paTIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC43OiByb3cgKz0gXFxcIuKWkiBcXFwiXFxuICAgICAgICBlbHNlOiByb3cgKz0gXFxcIuKWiCBcXFwiXFxuICAgIHByaW50KGZcXFwiICBSb3cge2d5fTogfHtyb3d9fFxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFkMjc2ZjdlMDQzYjhmODYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxuICBSb3cgMDogfCAgwrcgwrcgICAgICAgICDCtyDCtyDCtyB8XFxuICBSb3cgMTogfOKAoiDCtyAgICAgwrcg4oCiIOKAoiDCtyDCtyAgIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXiyDigKIgwrcgICAgICAgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkyDil48gwrcgICAgICAgICAgICAgfFxcbiAgUm93IDQ6IHzilpIg4paSIOKWkyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNTogfOKWkyDil48g4paTIOKXjyDil48gwrcgICAgICAgICB8XFxuICBSb3cgNjogfCAg4pePIOKWkiDilpIg4paSIOKWkyDilpMg4peLIOKAoiAgIHxcXG4gIFJvdyA3OiB84pePIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMg4paTIHxcXG4gIFJvdyA4OiB84paIIOKWiCDilogg4paIIOKWiCDilpIg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA5OiB84paSIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paTIHxcXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:20:27 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301624-FaLWAWddqFFmVQRTY9yi", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca3aff6b34f76f-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301624-FaLWAWddqFFmVQRTY9yi\",\"object\":\"chat.completion\",\"created\":1784301624,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-ac68c75cb6cd7431\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":52392,\"completion_tokens\":22,\"total_tokens\":52414,\"cost\":0.00969643248,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":51712,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00969643248,\"upstream_inference_prompt_cost\":0.00963167328,\"upstream_inference_completions_cost\":0.0000647592},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAp7ImlkIjoiZ2VuLTE3ODQzMDE2MjQtRmFMV0FXZGRxRkZtVlFSVFk5eWkiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24iLCJjcmVhdGVkIjoxNzg0MzAxNjI0LCJtb2RlbCI6InotYWkvZ2xtLTUuMiIsInByb3ZpZGVyIjoiTm92aXRhIiwic3lzdGVtX2ZpbmdlcnByaW50IjpudWxsLCJzZXJ2aWNlX3RpZXIiOm51bGwsImNob2ljZXMiOlt7ImluZGV4IjowLCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJuYXRpdmVfZmluaXNoX3JlYXNvbiI6InRvb2xfY2FsbHMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJyZWZ1c2FsIjpudWxsLCJyZWFzb25pbmciOm51bGwsInRvb2xfY2FsbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImluZGV4IjowLCJpZCI6ImNoYXRjbXBsLXRvb2wtYWM2OGM3NWNiNmNkNzQzMSIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19fV0sInVzYWdlIjp7InByb21wdF90b2tlbnMiOjUyMzkyLCJjb21wbGV0aW9uX3Rva2VucyI6MjIsInRvdGFsX3Rva2VucyI6NTI0MTQsImNvc3QiOjAuMDA5Njk2NDMyNDgsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6NTE3MTIsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDA5Njk2NDMyNDgsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDk2MzE2NzMyOCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAwMDY0NzU5Mn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-ac68c75cb6cd7431", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}], "tokens_in": 52392, "tokens_out": 22, "cost_usd": 0.00969643248, "cached_tokens": 51712}, "error": null}
{"ts": "2026-07-17T15:20:27.285226+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-ac68c75cb6cd7431", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:20:27.285226+00:00", "type": "tool_call", "id": "chatcmpl-tool-ac68c75cb6cd7431", "name": "get_screenshot_of_area_as_image", "arguments": {"area_ui_type": "VIEW_3D"}, "raw_arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}
{"ts": "2026-07-17T15:20:27.737510+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-ac68c75cb6cd7431", "name": "get_screenshot_of_area_as_image", "text": "", "is_error": false, "has_image": true, "image_b64": "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"}
{"ts": "2026-07-17T15:20:49.468471+00:00", "type": "llm_call", "call_index": 68, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:20:27.740590+00:00", "finished_at": "2026-07-17T15:20:49.467472+00:00", "duration_s": 21.73399999999674, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}"}, {"role": "assistant", "content": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a1bde82900051568", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▒ ● ·             |\\n  Row 4: |█ ▒ ● ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8bf5081c37eebeb6", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8bf5081c37eebeb6", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-96f3c02259f22638", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check the right side of the image for green\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed color check on the right portion\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    if brightness < 0.05:\\n        continue\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check the right side specifically\\nright_g = 0\\nright_t = 0\\nfor y in range(h):\\n    for x in range(int(w*0.7), w, 3):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_t += 1\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\n                right_g += 1\\nprint(f\\\"Right side green: {100*right_g/right_t:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-96f3c02259f22638", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\nRight side green: 10.8%\\n\"\n}"}, {"role": "assistant", "content": "Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.", "tool_calls": [{"id": "chatcmpl-tool-99ced8845b19cf57", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# CANDLESTICK with candle - additional classical prop\\n# Justifies the warm light source\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"CandlestickMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the candlestick (radius, height) — lathed\\nstick_profile = [\\n    (0.00, 0.00),    # center bottom\\n    (0.12, 0.00),    # base edge\\n    (0.13, 0.01),    # base lip\\n    (0.12, 0.03),    # \\n    (0.08, 0.04),    # base to stem\\n    (0.05, 0.06),    # stem base\\n    (0.04, 0.15),    # stem\\n    (0.04, 0.25),    # stem\\n    (0.05, 0.30),    # mid decorative\\n    (0.04, 0.35),    # \\n    (0.035, 0.40),   # upper stem\\n    (0.05, 0.44),    # candle cup base\\n    (0.06, 0.46),    # cup\\n    (0.055, 0.48),   # cup lip\\n    (0.04, 0.50),    # cup inner\\n    (0.00, 0.50),    # center top\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in stick_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = stick_profile[ri]\\n    rb, _ = stick_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nstick_obj = bpy.data.objects.new(\\\"Candlestick\\\", mesh)\\nlink_obj(stick_obj)\\nstick_obj.location = (-1.6, 0.8, 0.0)\\nbpy.context.view_layer.objects.active = stick_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = stick_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# Candle\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\ncandle = bpy.context.active_object\\ncandle.name = \\\"Candle\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Candle flame - a small emissive shape\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\nflame = bpy.context.active_object\\nflame.name = \\\"CandleFlame\\\"\\nflame.scale = (0.6, 0.6, 1.8)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\nbpy.ops.object.shade_smooth()\\n\\nprint(\\\"Candlestick with candle and flame built.\\\")\\nresult = {\\\"candlestick\\\": stick_obj.name, \\\"candle\\\": candle.name, \\\"flame\\\": flame.name}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-99ced8845b19cf57", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"candlestick\": \"Candlestick\",\n    \"candle\": \"Candle\",\n    \"flame\": \"CandleFlame\"\n  },\n  \"stdout\": \"Candlestick with candle and flame built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-86253733bb060d5b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- Candlestick: Aged brass/bronze ---\\nmat, nt = create_material(\\\"M_CandlestickBrass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 5.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 40.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Candlestick\\\"].data.materials.append(mat)\\n\\n# --- Candle: Waxed off-white ---\\nmat, nt = create_material(\\\"M_Candle\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.5\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Candle\\\"].data.materials.append(mat)\\n\\n# --- Candle flame: Emissive ---\\nmat, nt = create_material(\\\"M_CandleFlame\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\nemission.inputs['Strength'].default_value = 15.0\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\nbpy.data.objects[\\\"CandleFlame\\\"].data.materials.append(mat)\\n\\n# Add a point light at the flame for actual illumination\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\nflame_light = bpy.context.active_object\\nflame_light.name = \\\"CandleLight\\\"\\nflame_light.data.energy = 50\\nflame_light.data.color = (1.0, 0.7, 0.3)\\nflame_light.data.shadow_soft_size = 0.05\\n\\nprint(\\\"Candlestick, candle, and flame materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-86253733bb060d5b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Candlestick, candle, and flame materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad276f7e043b8f86", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render with candle\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview8.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview8.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad276f7e043b8f86", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▓ ● ·             |\\n  Row 4: |▒ ▒ ▓ ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ ▒ ▓ ▓ ○ •   |\\n  Row 7: |● █ █ █ ▒ ▒ ▒ ▒ ▓ ▓ |\\n  Row 8: |█ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 9: |▒ █ █ █ █ █ █ ▒ ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ac68c75cb6cd7431", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac68c75cb6cd7431", "content": ""}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:20:27.740590+00:00", "finished_at": "2026-07-17T15:20:49.466473+00:00", "duration_s": 21.73399999999674, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "196797", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9cddced158a16a7f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Connected bump to BSDF Normal\\\\nConnected BSDF to output\\\\n\\\\nFinal links:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n  Bump.Normal -> Principled BSDF.Normal\\\\n  Principled BSDF.BSDF -> Material Output.Surface\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good, Suzanne material is fixed. Now let me render to check everything looks good.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a1bde82900051568\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a1bde82900051568\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▒ ● ·             |\\\\n  Row 4: |█ ▒ ● ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-96f3c02259f22638\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check the right side of the image for green\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed color check on the right portion\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    if brightness < 0.05:\\\\n        continue\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check the right side specifically\\\\nright_g = 0\\\\nright_t = 0\\\\nfor y in range(h):\\\\n    for x in range(int(w*0.7), w, 3):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_t += 1\\\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\\\n                right_g += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_g/right_t:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-96f3c02259f22638\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\\\nRight side green: 10.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-99ced8845b19cf57\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# CANDLESTICK with candle - additional classical prop\\\\n# Justifies the warm light source\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"CandlestickMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the candlestick (radius, height) — lathed\\\\nstick_profile = [\\\\n    (0.00, 0.00),    # center bottom\\\\n    (0.12, 0.00),    # base edge\\\\n    (0.13, 0.01),    # base lip\\\\n    (0.12, 0.03),    # \\\\n    (0.08, 0.04),    # base to stem\\\\n    (0.05, 0.06),    # stem base\\\\n    (0.04, 0.15),    # stem\\\\n    (0.04, 0.25),    # stem\\\\n    (0.05, 0.30),    # mid decorative\\\\n    (0.04, 0.35),    # \\\\n    (0.035, 0.40),   # upper stem\\\\n    (0.05, 0.44),    # candle cup base\\\\n    (0.06, 0.46),    # cup\\\\n    (0.055, 0.48),   # cup lip\\\\n    (0.04, 0.50),    # cup inner\\\\n    (0.00, 0.50),    # center top\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in stick_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = stick_profile[ri]\\\\n    rb, _ = stick_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nstick_obj = bpy.data.objects.new(\\\\\\\"Candlestick\\\\\\\", mesh)\\\\nlink_obj(stick_obj)\\\\nstick_obj.location = (-1.6, 0.8, 0.0)\\\\nbpy.context.view_layer.objects.active = stick_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = stick_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# Candle\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\\\ncandle = bpy.context.active_object\\\\ncandle.name = \\\\\\\"Candle\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Candle flame - a small emissive shape\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\\\nflame = bpy.context.active_object\\\\nflame.name = \\\\\\\"CandleFlame\\\\\\\"\\\\nflame.scale = (0.6, 0.6, 1.8)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nprint(\\\\\\\"Candlestick with candle and flame built.\\\\\\\")\\\\nresult = {\\\\\\\"candlestick\\\\\\\": stick_obj.name, \\\\\\\"candle\\\\\\\": candle.name, \\\\\\\"flame\\\\\\\": flame.name}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-99ced8845b19cf57\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"candlestick\\\": \\\"Candlestick\\\",\\n    \\\"candle\\\": \\\"Candle\\\",\\n    \\\"flame\\\": \\\"CandleFlame\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick with candle and flame built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-86253733bb060d5b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- Candlestick: Aged brass/bronze ---\\\\nmat, nt = create_material(\\\\\\\"M_CandlestickBrass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 5.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 40.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Candlestick\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle: Waxed off-white ---\\\\nmat, nt = create_material(\\\\\\\"M_Candle\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.5\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Candle\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle flame: Emissive ---\\\\nmat, nt = create_material(\\\\\\\"M_CandleFlame\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\\\nemission.inputs['Strength'].default_value = 15.0\\\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"CandleFlame\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Add a point light at the flame for actual illumination\\\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\\\nflame_light = bpy.context.active_object\\\\nflame_light.name = \\\\\\\"CandleLight\\\\\\\"\\\\nflame_light.data.energy = 50\\\\nflame_light.data.color = (1.0, 0.7, 0.3)\\\\nflame_light.data.shadow_soft_size = 0.05\\\\n\\\\nprint(\\\\\\\"Candlestick, candle, and flame materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-86253733bb060d5b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick, candle, and flame materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad276f7e043b8f86\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render with candle\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview8.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview8.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad276f7e043b8f86\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▓ ● ·             |\\\\n  Row 4: |▒ ▒ ▓ ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ ▒ ▓ ▓ ○ •   |\\\\n  Row 7: |● █ █ █ ▒ ▒ ▒ ▒ ▓ ▓ |\\\\n  Row 8: |█ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 9: |▒ █ █ █ █ █ █ ▒ ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac68c75cb6cd7431\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac68c75cb6cd7431\",\"content\":\"\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWNkZGNlZDE1OGExNmE3ZiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBDb25uZWN0IGJ1bXAgdG8gQlNERiBOb3JtYWwgYW5kIEJTREYgdG8gb3V0cHV0XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5cXG4jIE1ha2Ugc3VyZSBidW1wIG5vcm1hbCBnb2VzIHRvIEJTREZcXG5idW1wID0gTm9uZVxcbmJzZGYgPSBOb25lXFxub3V0cHV0ID0gTm9uZVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ0JVTVAnOlxcbiAgICAgICAgYnVtcCA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ0JTREZfUFJJTkNJUExFRCc6XFxuICAgICAgICBic2RmID0gbm9kZVxcbiAgICBlbGlmIG5vZGUudHlwZSA9PSAnT1VUUFVUX01BVEVSSUFMJzpcXG4gICAgICAgIG91dHB1dCA9IG5vZGVcXG5cXG5pZiBidW1wIGFuZCBic2RmOlxcbiAgICBudC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXFwiKVxcblxcbmlmIGJzZGYgYW5kIG91dHB1dDpcXG4gICAgbnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuICAgIHByaW50KFxcXCJDb25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXFwiKVxcblxcbnByaW50KFxcXCJcXFxcbkZpbmFsIGxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05Y2RkY2VkMTU4YTE2YTdmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXG5Db25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXG5cXG5GaW5hbCBsaW5rczpcXG4gIFRleHR1cmUgQ29vcmRpbmF0ZS5HZW5lcmF0ZWQgLT4gTWFwcGluZy5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IE5vaXNlIFRleHR1cmUuVmVjdG9yXFxuICBNYXBwaW5nLlZlY3RvciAtPiBXYXZlIFRleHR1cmUuVmVjdG9yXFxuICBXYXZlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkFcXG4gIE5vaXNlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkJcXG4gIE1peC5SZXN1bHQgLT4gQ29sb3IgUmFtcC5GYWN0b3JcXG4gIENvbG9yIFJhbXAuQ29sb3IgLT4gUHJpbmNpcGxlZCBCU0RGLkJhc2UgQ29sb3JcXG4gIE5vaXNlIFRleHR1cmUuMDAxLkZhY3RvciAtPiBCdW1wLkhlaWdodFxcbiAgQnVtcC5Ob3JtYWwgLT4gUHJpbmNpcGxlZCBCU0RGLk5vcm1hbFxcbiAgUHJpbmNpcGxlZCBCU0RGLkJTREYgLT4gTWF0ZXJpYWwgT3V0cHV0LlN1cmZhY2VcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kLCBTdXphbm5lIG1hdGVyaWFsIGlzIGZpeGVkLiBOb3cgbGV0IG1lIHJlbmRlciB0byBjaGVjayBldmVyeXRoaW5nIGxvb2tzIGdvb2QuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWExYmRlODI5MDAwNTE1NjgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc3LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTFiZGU4MjkwMDA1MTU2OCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8ICDCtyDCtyAgICAgICAgIMK3IMK3IMK3IHxcXG4gIFJvdyAxOiB84oCiIMK3ICAgICDCtyDigKIg4oCiIMK3IMK3ICAgfFxcbiAgUm93IDI6IHzCtyDigKIg4peLIOKAoiDCtyAgICAgICAgICAgfFxcbiAgUm93IDM6IHzilpMg4paSIOKXjyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNDogfOKWiCDilpIg4pePIMK3ICAgICAgICAgICAgIHxcXG4gIFJvdyA1OiB84paTIOKXjyDilpMg4pePIOKXjyDCtyAgICAgICAgIHxcXG4gIFJvdyA2OiB8ICDil48g4paSIOKWkiDilogg4paSIOKWkyDil4sg4oCiICAgfFxcbiAgUm93IDc6IHzil4sg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDg6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paSIOKWkiDilpIgfFxcbiAgUm93IDk6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLThiZjUwODFjMzdlZWJlYjYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04YmY1MDgxYzM3ZWViZWI2IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIG9mIHRoZSBpbWFnZSBmb3IgZ3JlZW5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgRGV0YWlsZWQgY29sb3IgY2hlY2sgb24gdGhlIHJpZ2h0IHBvcnRpb25cXG5yZWRfY291bnQgPSAwXFxuZ3JlZW5fY291bnQgPSAwXFxud2FybV9jb3VudCA9IDBcXG50b3RhbCA9IDBcXG5cXG5mb3IgaSBpbiByYW5nZSgwLCBsZW4ocGl4ZWxzKSwgNCk6XFxuICAgIHIsIGcsIGIgPSBwaXhlbHNbaV0sIHBpeGVsc1tpKzFdLCBwaXhlbHNbaSsyXVxcbiAgICB0b3RhbCArPSAxXFxuICAgIGJyaWdodG5lc3MgPSAociArIGcgKyBiKSAvIDNcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgZWxpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgIGVsaWYgciA+IDAuMiBhbmQgZyA+IDAuMTUgYW5kIHIgPiBiICogMS4zOlxcbiAgICAgICAgd2FybV9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJSZWQ6IHsxMDAqcmVkX2NvdW50L3RvdGFsOi4xZn0lLCBHcmVlbjogezEwMCpncmVlbl9jb3VudC90b3RhbDouMWZ9JSwgV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIHNwZWNpZmljYWxseVxcbnJpZ2h0X2cgPSAwXFxucmlnaHRfdCA9IDBcXG5mb3IgeSBpbiByYW5nZShoKTpcXG4gICAgZm9yIHggaW4gcmFuZ2UoaW50KHcqMC43KSwgdywgMyk6XFxuICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICByLCBnLCBiID0gcGl4ZWxzW2lkeF0sIHBpeGVsc1tpZHgrMV0sIHBpeGVsc1tpZHgrMl1cXG4gICAgICAgICAgICByaWdodF90ICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4wOCBhbmQgZyA+IHIgKiAxLjE1IGFuZCBnID4gYiAqIDEuMTU6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2cgKz0gMVxcbnByaW50KGZcXFwiUmlnaHQgc2lkZSBncmVlbjogezEwMCpyaWdodF9nL3JpZ2h0X3Q6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkOiAxNC4wJSwgR3JlZW46IDMuOCUsIFdhcm06IDMxLjQlXFxuUmlnaHQgc2lkZSBncmVlbjogMTAuOCVcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kIC0gZ3JlZW4gaXMgbm93IHZpc2libGUgb24gdGhlIHJpZ2h0IHNpZGUuIFRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgd2l0aCByZWQgb24gdGhlIGxlZnQsIGdyZWVuIG9uIHRoZSByaWdodCAoQ29ybmVsbCBib3ggcGFsZXR0ZSksIHdhcm0gbGlnaHQsIGFuZCBkYXJrIHNoYWRvd3MuIExldCBtZSBub3cgYWRkIHNvbWUgZmluYWwgcG9saXNoOiBhIGNhbmRsZXN0aWNrIGFzIGFuIGFkZGl0aW9uYWwgY2xhc3NpY2FsIHByb3AgKHdoaWNoIGFsc28ganVzdGlmaWVzIHRoZSB3YXJtIGxpZ2h0IHNvdXJjZSksIGFuZCBtYWtlIGFkanVzdG1lbnRzIHRvIHRoZSBTdXphbm5lIGJ1c3QgcG9zaXRpb25pbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk5Y2VkODg0NWIxOWNmNTciLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ0FORExFU1RJQ0sgd2l0aCBjYW5kbGUgLSBhZGRpdGlvbmFsIGNsYXNzaWNhbCBwcm9wXFxuIyBKdXN0aWZpZXMgdGhlIHdhcm0gbGlnaHQgc291cmNlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQ2FuZGxlc3RpY2tNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSBjYW5kbGVzdGljayAocmFkaXVzLCBoZWlnaHQpIOKAlCBsYXRoZWRcXG5zdGlja19wcm9maWxlID0gW1xcbiAgICAoMC4wMCwgMC4wMCksICAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4xMiwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjEzLCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMiwgMC4wMyksICAgICMgXFxuICAgICgwLjA4LCAwLjA0KSwgICAgIyBiYXNlIHRvIHN0ZW1cXG4gICAgKDAuMDUsIDAuMDYpLCAgICAjIHN0ZW0gYmFzZVxcbiAgICAoMC4wNCwgMC4xNSksICAgICMgc3RlbVxcbiAgICAoMC4wNCwgMC4yNSksICAgICMgc3RlbVxcbiAgICAoMC4wNSwgMC4zMCksICAgICMgbWlkIGRlY29yYXRpdmVcXG4gICAgKDAuMDQsIDAuMzUpLCAgICAjIFxcbiAgICAoMC4wMzUsIDAuNDApLCAgICMgdXBwZXIgc3RlbVxcbiAgICAoMC4wNSwgMC40NCksICAgICMgY2FuZGxlIGN1cCBiYXNlXFxuICAgICgwLjA2LCAwLjQ2KSwgICAgIyBjdXBcXG4gICAgKDAuMDU1LCAwLjQ4KSwgICAjIGN1cCBsaXBcXG4gICAgKDAuMDQsIDAuNTApLCAgICAjIGN1cCBpbm5lclxcbiAgICAoMC4wMCwgMC41MCksICAgICMgY2VudGVyIHRvcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBzdGlja19wcm9maWxlOlxcbiAgICByaW5nID0gW11cXG4gICAgaWYgciA8IDAuMDAxOlxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4oYWxsX3ZlcnRzKSAtIDEpOlxcbiAgICByaW5nX2EgPSBhbGxfdmVydHNbcmldXFxuICAgIHJpbmdfYiA9IGFsbF92ZXJ0c1tyaSArIDFdXFxuICAgIHJhLCBfID0gc3RpY2tfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBzdGlja19wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuc3RpY2tfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkNhbmRsZXN0aWNrXFxcIiwgbWVzaClcXG5saW5rX29iaihzdGlja19vYmopXFxuc3RpY2tfb2JqLmxvY2F0aW9uID0gKC0xLjYsIDAuOCwgMC4wKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBzdGlja19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IHN0aWNrX29iai5tb2RpZmllcnMubmV3KFxcXCJTdWJzdXJmXFxcIiwgJ1NVQlNVUkYnKVxcbm1vZC5sZXZlbHMgPSAxXFxubW9kLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuIyBDYW5kbGVcXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX2N5bGluZGVyX2FkZChyYWRpdXM9MC4wMzUsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgtMS42LCAwLjgsIDAuNTc1KSlcXG5jYW5kbGUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuY2FuZGxlLm5hbWUgPSBcXFwiQ2FuZGxlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBDYW5kbGUgZmxhbWUgLSBhIHNtYWxsIGVtaXNzaXZlIHNoYXBlXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz0wLjAzLCBzZWdtZW50cz0xNiwgcmluZ19jb3VudD04LCBsb2NhdGlvbj0oLTEuNiwgMC44LCAwLjcwKSlcXG5mbGFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5mbGFtZS5uYW1lID0gXFxcIkNhbmRsZUZsYW1lXFxcIlxcbmZsYW1lLnNjYWxlID0gKDAuNiwgMC42LCAxLjgpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1GYWxzZSwgc2NhbGU9VHJ1ZSlcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbnByaW50KFxcXCJDYW5kbGVzdGljayB3aXRoIGNhbmRsZSBhbmQgZmxhbWUgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNhbmRsZXN0aWNrXFxcIjogc3RpY2tfb2JqLm5hbWUsIFxcXCJjYW5kbGVcXFwiOiBjYW5kbGUubmFtZSwgXFxcImZsYW1lXFxcIjogZmxhbWUubmFtZX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05OWNlZDg4NDViMTljZjU3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjYW5kbGVzdGlja1wiOiBcIkNhbmRsZXN0aWNrXCIsXG4gICAgXCJjYW5kbGVcIjogXCJDYW5kbGVcIixcbiAgICBcImZsYW1lXCI6IFwiQ2FuZGxlRmxhbWVcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbmRsZXN0aWNrIHdpdGggY2FuZGxlIGFuZCBmbGFtZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NjI1MzczM2JiMDYwZDViIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIENhbmRsZXN0aWNrOiBBZ2VkIGJyYXNzL2Jyb256ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZXN0aWNrQnJhc3NcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDIsIDAuMjAsIDEuMCkgICMgYnJhc3NcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjM1XFxuXFxuIyBQYXRpbmEgdmFyaWF0aW9uXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNS4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MiwgMC4yMCwgMS4wKSAgIyBicmFzc1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjM1LCAwLjIwLCAxLjApICAjIHBhdGluYVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkNhbmRsZXN0aWNrXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGU6IFdheGVkIG9mZi13aGl0ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MiwgMC43MiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGUgZmxhbWU6IEVtaXNzaXZlIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQ2FuZGxlRmxhbWVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuZW1pc3Npb24gPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVFbWlzc2lvbicsICgyMDAsIDApKVxcbmVtaXNzaW9uLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDEuMCwgMC43LCAwLjMsIDEuMCkgICMgd2FybSBmbGFtZVxcbmVtaXNzaW9uLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm50LmxpbmtzLm5ldyhlbWlzc2lvbi5vdXRwdXRzWydFbWlzc2lvbiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlRmxhbWVcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgQWRkIGEgcG9pbnQgbGlnaHQgYXQgdGhlIGZsYW1lIGZvciBhY3R1YWwgaWxsdW1pbmF0aW9uXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J1BPSU5UJywgbG9jYXRpb249KC0xLjYsIDAuOCwgMC43MikpXFxuZmxhbWVfbGlnaHQgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxhbWVfbGlnaHQubmFtZSA9IFxcXCJDYW5kbGVMaWdodFxcXCJcXG5mbGFtZV9saWdodC5kYXRhLmVuZXJneSA9IDUwXFxuZmxhbWVfbGlnaHQuZGF0YS5jb2xvciA9ICgxLjAsIDAuNywgMC4zKVxcbmZsYW1lX2xpZ2h0LmRhdGEuc2hhZG93X3NvZnRfc2l6ZSA9IDAuMDVcXG5cXG5wcmludChcXFwiQ2FuZGxlc3RpY2ssIGNhbmRsZSwgYW5kIGZsYW1lIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2MjUzNzMzYmIwNjBkNWIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJDYW5kbGVzdGljaywgY2FuZGxlLCBhbmQgZmxhbWUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWQyNzZmN2UwNDNiOGY4NiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBSZW5kZXIgd2l0aCBjYW5kbGVcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3OC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc4LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDEweDEwIGdyaWQpOlxcXCIpXFxuZm9yIGd5IGluIHJhbmdlKDEwKTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDEwKTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDEwXFxuICAgICAgICB4MiA9IChneCsxKSAqIHcgLy8gMTBcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDEwXFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gMTBcXG4gICAgICAgIGJyaWdodF9zdW0gPSAwXFxuICAgICAgICBjb3VudCA9IDBcXG4gICAgICAgIGZvciB5IGluIHJhbmdlKHkxLCB5MiwgMjUpOlxcbiAgICAgICAgICAgIGZvciB4IGluIHJhbmdlKHgxLCB4MiwgMjUpOlxcbiAgICAgICAgICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgICAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgICAgICAgICAgYnJpZ2h0X3N1bSArPSAocGl4ZWxzW2lkeF0gKyBwaXhlbHNbaWR4KzFdICsgcGl4ZWxzW2lkeCsyXSkgLyAzXFxuICAgICAgICAgICAgICAgICAgICBjb3VudCArPSAxXFxuICAgICAgICBicmlnaHQgPSBicmlnaHRfc3VtIC8gY291bnQgaWYgY291bnQgPiAwIGVsc2UgMFxcbiAgICAgICAgaWYgYnJpZ2h0IDwgMC4wNjogcm93ICs9IFxcXCIgIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4xMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40OiByb3cgKz0gXFxcIuKXjyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNTU6IHJvdyArPSBcXFwi4paTIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC43OiByb3cgKz0gXFxcIuKWkiBcXFwiXFxuICAgICAgICBlbHNlOiByb3cgKz0gXFxcIuKWiCBcXFwiXFxuICAgIHByaW50KGZcXFwiICBSb3cge2d5fTogfHtyb3d9fFxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFkMjc2ZjdlMDQzYjhmODYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxuICBSb3cgMDogfCAgwrcgwrcgICAgICAgICDCtyDCtyDCtyB8XFxuICBSb3cgMTogfOKAoiDCtyAgICAgwrcg4oCiIOKAoiDCtyDCtyAgIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXiyDigKIgwrcgICAgICAgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkyDil48gwrcgICAgICAgICAgICAgfFxcbiAgUm93IDQ6IHzilpIg4paSIOKWkyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNTogfOKWkyDil48g4paTIOKXjyDil48gwrcgICAgICAgICB8XFxuICBSb3cgNjogfCAg4pePIOKWkiDilpIg4paSIOKWkyDilpMg4peLIOKAoiAgIHxcXG4gIFJvdyA3OiB84pePIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMg4paTIHxcXG4gIFJvdyA4OiB84paIIOKWiCDilogg4paIIOKWiCDilpIg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA5OiB84paSIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paTIHxcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hYzY4Yzc1Y2I2Y2Q3NDMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWM2OGM3NWNiNmNkNzQzMSIsImNvbnRlbnQiOiIifV0sInVzYWdlIjp7ImluY2x1ZGUiOnRydWV9LCJ0b29scyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiB0aGUgY29ubmVjdGVkIEJsZW5kZXIgaW5zdGFuY2UuXG5cbiAgICAgICAgVGhlIGNvZGUgcnVucyBpbiBCbGVuZGVyJ3MgUHl0aG9uIGVudmlyb25tZW50IHdpdGggZnVsbCBhY2Nlc3MgdG8gYGBicHlgYC5cbiAgICAgICAgVG8gcmV0dXJuIGRhdGEsIGFzc2lnbiBhIEpTT04tc2VyaWFsaXNhYmxlIGRpY3QgdG8gYSB2YXJpYWJsZSBuYW1lZCBgYHJlc3VsdGBgLlxuICAgICAgICBEZWZlcnJlZCBjb21wbGV0aW9uIHZpYSBgYGNoZWNrX2lzX2ZpbmlzaGVkYGAgaXMgb25seSBzdXBwb3J0ZWQgYnkgdGhlXG4gICAgICAgIGludGVyYWN0aXZlIGFkZG9uIHNlcnZlciwgYW5kIGlzIHJlamVjdGVkIGluIGJhY2tncm91bmQgbW9kZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gYSBiYWNrZ3JvdW5kIEJsZW5kZXIgcHJvY2Vzcy5cblxuICAgICAgICBPcGVucyAqYmxlbmRfZmlsZSogd2l0aCBgYGJsZW5kZXIgLS1iYWNrZ3JvdW5kYGAgYW5kIHJ1bnMgKmNvZGUqLlxuICAgICAgICBBc3NpZ24gYSBkaWN0IHRvIGBgcmVzdWx0YGAgdG8gcmV0dXJuIGRhdGEuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifSwiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIiwiY29kZSJdLCJ0aXRsZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2NrcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN1bW1hcnkgb2YgdGhlIGJsZW5kIGZpbGU6IGRhdGEtYmxvY2sgY291bnRzLCBhY3RpdmUgd29ya3NwYWNlLCBhbmQgcmVuZGVyIGVuZ2luZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBkYXRhLWJsb2NrIHN1bW1hcnkgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IGV4dGVybmFsIGZpbGUgcmVmZXJlbmNlcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gZGlza1xuICAgICAgICAoaW1hZ2VzLCBsaWJyYXJpZXMsIGZvbnRzLCBzb3VuZHMsIG1vdmllIGNsaXBzLCBjYWNoZXMsIHNlcXVlbmNlcykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVwb3J0IG1pc3NpbmcgZmlsZSByZWZlcmVuY2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHRyZWUgb2YgZGlyZWN0bHkgYW5kIGluZGlyZWN0bHkgbGlua2VkIGxpYnJhcnkgZmlsZXMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGxpbmtlZC1saWJyYXJ5IGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm8iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTaW1wbGUvZmFzdCBhY2Nlc3MgdG8gdGhlIGJsZW5kIGZpbGUncyBwYXRoLCBzYXZlIHN0YXR1cywgYWdlLCBhbmQgYmFja3Vwcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHBhdGggaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB0aGUgcHJpbWFyeSB1c2UtY2FzZXMgb2YgdGhlIGN1cnJlbnQgYmxlbmQgZmlsZSAoc2NvcmVkIDAtMTAwIHdpdGggY2VydGFpbnR5KS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHVzZS1jYXNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfdXNhZ2VfZ3Vlc3NfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdHJ1Y3R1cmVkIHN1bW1hcnkgb2YgdGhlIG9iamVjdCBpZGVudGlmaWVkIGJ5ICpuYW1lKi5cblxuICAgICAgICBJbmNsdWRlcyB0eXBlLCB0cmFuc2Zvcm1zLCBwYXJlbnQsIGNoaWxkcmVuLCBtb2RpZmllcnMsIGNvbnN0cmFpbnRzLFxuICAgICAgICBtYXRlcmlhbHMsIHZpc2liaWxpdHksIGRhdGEtYmxvY2sgbmFtZSwgYW5kIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIHNjZW5lJ3MgY29sbGVjdGlvbiBoaWVyYXJjaHkgYW5kIHRoZWlyIG9iamVjdHMuXG5cbiAgICAgICAgRWFjaCBjb2xsZWN0aW9uIGxpc3RzIGl0cyBvYmplY3RzIChuYW1lLCB0eXBlLCBwYXJlbnQsIGRhdGEgbmFtZSxcbiAgICAgICAgc2VsZWN0aW9uLCB2aXNpYmlsaXR5KSBhbmQgbmVzdGVkIGNoaWxkIGNvbGxlY3Rpb25zLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9vYmplY3RzX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBCbGVuZGVyIFB5dGhvbiBBUEkgZG9jcyBmb3IgKmlkZW50aWZpZXIqLCBvciBsaXN0XG4gICAgICAgIG1vZHVsZXMgbWF0Y2hpbmcgYSB0cmFpbGluZy1gYCpgYCBkaXNjb3ZlcnkgcGF0dGVybi5cblxuICAgICAgICAqaWRlbnRpZmllciogc2hvdWxkIGJlIGEgZnVsbHktcXVhbGlmaWVkIFB5dGhvbiBuYW1lIChlLmcuXG4gICAgICAgIGBgYnB5LmFwcGBgIG9yIGBgYnB5LnR5cGVzLlNjZW5lLmZyYW1lX2N1cnJlbnRgYCkuXG4gICAgICAgIFRoZSB0cmFpbGluZy1gYCpgYCBmb3JtcyBhcmUgc3VwcG9ydGVkIGFzIGRpc2NvdmVyeSBlbnRyeS1wb2ludHM6XG5cbiAgICAgICAgLSBgYCpgYCBlbnVtZXJhdGVzIHRoZSB0b3AtbGV2ZWwgbW9kdWxlcyAoYGBicHlgYCwgYGBibWVzaGBgLFxuICAgICAgICAgIGBgbWF0aHV0aWxzYGAsIGBgZ3B1YGAsIC4uLikuXG4gICAgICAgIC0gYGBYLipgYCBlbnVtZXJhdGVzIHRoZSBkaXJlY3QtY2hpbGQgaWRlbnRpZmllcnMgdW5kZXIgdGhlXG4gICAgICAgICAgKlgqIG5hbWVzcGFjZSAoYGBicHkuKmBgIC0+IGBgYnB5LmFwcGBgLCBgYGJweS5jb250ZXh0YGAsIC4uLikuXG5cbiAgICAgICAgQm90aCByZXR1cm4gYSBgYG5hbWVzcGFjZWBgIHJlc3BvbnNlIGV2ZW4gd2hlbiBgYFgucnN0YGAgd291bGRcbiAgICAgICAgb3RoZXJ3aXNlIHJlc29sdmUgdG8gYGBleGFjdGBgOyB0aGUgYGAuKmBgIGZvcm0gbGV0cyBhbiBhZ2VudFxuICAgICAgICBmb3JjZSB0aGUgY2hpbGQgbGlzdGluZy5cblxuICAgICAgICBUaGUgcmVzcG9uc2UgYWx3YXlzIGNhcnJpZXMgYGBraW5kYGAsIGBgZm91bmRgYCwgYW5kIGBgaWRlbnRpZmllcmBgLlxuICAgICAgICBUaGUgcmVtYWluaW5nIGtleXMgZGVwZW5kIG9uIGBga2luZGBgOlxuXG4gICAgICAgIC0gYGBcImV4YWN0XCJgYCAoYGBmb3VuZD1UcnVlYGApOiBgYDxpZGVudGlmaWVyPi5yc3RgYCB3YXMgcmVhZC5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAoUlNUIHRleHQpLCBgYGV4YW1wbGVzYGAuIFdoZW4gdGhlXG4gICAgICAgICAgZmlsZSBleGNlZWRzIDMyIEtCLCBgYGNvbnRlbnRgYCBpcyByZXBsYWNlZCB3aXRoIGEgZG90LXBvaW50XG4gICAgICAgICAgc3VtbWFyeSBvZiB0aGUgZmlsZSdzIHRvcC1sZXZlbCBkZWZpbml0aW9ucyAocHJlZml4ZWQgYnkgYVxuICAgICAgICAgIGhlYWRlciBub3RpbmcgdGhlIHRydW5jYXRpb24pIGFuZCBgYGV4YW1wbGVzYGAgaXMgZW1wdHkgLVxuICAgICAgICAgIHJlLXF1ZXJ5IGluZGl2aWR1YWwgbWVtYmVycyBmb3IgdGhlaXIgcmVuZGVyZWQgYmxvY2tzLlxuICAgICAgICAtIGBgXCJuYW1lc3BhY2VcImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgbm8gYGA8aWRlbnRpZmllcj4ucnN0YGAgYnV0IGBgPGlkZW50aWZpZXI+LjxjaGlsZD4ucnN0YGAgc2libGluZ3MgZXhpc3QuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Ym1vZHVsZXNgYCAobGlzdCBvZiBjaGlsZCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcImRlZmluaXRpb25cImBgIChgYGZvdW5kPVRydWVgYCk6XG4gICAgICAgICAgKmlkZW50aWZpZXIqIGlzIGRlZmluZWQgaW5zaWRlIGEgcGFyZW50IFJTVFxuICAgICAgICAgIChlLmcuIGBgYnB5LnByb3BzLkludFByb3BlcnR5YGAgbGl2ZXMgaW4gYGBicHkucHJvcHMucnN0YGApLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChyZW5kZXJlZCBibG9jayksIGBgZXhhbXBsZXNgYC5cbiAgICAgICAgLSBgYFwicGFydGlhbFwiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgdGhlIHBhcmVudCBSU1Qgd2FzIGxvY2F0ZWQgYnV0IHRoZSB0cmFpbGluZyBjb21wb25lbnQgaXNuJ3QgZGVmaW5lZCBpbiBpdC5cbiAgICAgICAgICBFeHRyYSBrZXlzOlxuICAgICAgICAgIC0gYGBwYXJlbnRgYCB0aGUgaWRlbnRpZmllciB3aG9zZSBSU1Qgd2FzIGxvYWRlZC5cbiAgICAgICAgICAtIGBgYXZhaWxhYmxlYGAgdG9wLWxldmVsIGRlZmluaXRpb25zIGluIHRoYXQgUlNULlxuICAgICAgICAgIC0gYGBzdWJtb2R1bGVzYGAgc2libGluZyBpZGVudGlmaWVycyBgYDxwYXJlbnQ+LjxjaGlsZD5gYCB3aXRoIHRoZWlyIG93biBSU1RzLFxuICAgICAgICAgICAgZmlsdGVyZWQgdG8gdGhvc2Ugd2hvc2UgbGFzdCBjb21wb25lbnQgY29udGFpbnMgZXZlcnkgY2hhcmFjdGVyIG9mIHRoZSBtaXNzaW5nIHRhaWwuXG5cbiAgICAgICAgICBGb3IgYSB0b2N0cmVlIGxhbmRpbmcgcGFnZSBsaWtlIGBgYnB5LnR5cGVzYGAgYGBhdmFpbGFibGVgYCBpcyBlbXB0eSBhbmQgYGBzdWJtb2R1bGVzYGBcbiAgICAgICAgICBpcyB0aGUgbmVhci1taXNzIGxpc3Q7IGZvciBhIHNlbGYtY29udGFpbmVkIG1vZHVsZSBsaWtlIGBgYnB5LnByb3BzYGAgaXQncyB0aGUgcmV2ZXJzZS5cbiAgICAgICAgLSBgYFwic3VnZ2VzdGlvbnNcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIG5vIGRpcmVjdCBtYXRjaCwgYnV0ICppZGVudGlmaWVyKiBhcHBlYXJzIGFzIGEgY29tcG9uZW50IG9mIG90aGVyIGZpbGVzLlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWdnZXN0aW9uc2BgIChsaXN0IG9mIGZ1bGwgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJtaXNzaW5nXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTogbm90aGluZyBtYXRjaGVkLlxuXG4gICAgICAgIGBgZXhhbXBsZXNgYCAocHJlc2VudCBvbiB0aGUgYGBleGFjdGBgIGFuZCBgYGRlZmluaXRpb25gYCBraW5kcylcbiAgICAgICAgaXMgYSBsaXN0IG9mIGBge3BhdGgsIGNvbnRlbnR9YGAgZW50cmllcyByZWZlcmVuY2VkIGZyb20gdGhpcyBkb2N1bWVudGF0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiaWRlbnRpZmllciI6eyJ0aXRsZSI6IklkZW50aWZpZXIiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJpZGVudGlmaWVyIl0sInRpdGxlIjoiZ2V0X3B5dGhvbl9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBUYWtlIGEgc2NyZWVuc2hvdCBvZiBhIHNpbmdsZSBCbGVuZGVyIGFyZWEgYW5kIHJldHVybiBpdCBhcyBhIFBORyBpbWFnZS5cblxuICAgICAgICAqYXJlYV91aV90eXBlKiBtYXRjaGVzIHRoZSBhcmVhJ3MgYGB1aV90eXBlYGAuXG5cbiAgICAgICAgKnNpemVfbGltaXRfaW5fYnl0ZXMqIGNhcHMgdGhlIGltYWdlIHNpemUgaW4gYnl0ZXMuXG4gICAgICAgIFplcm8gKHRoZSBkZWZhdWx0KSB1c2VzIHRoZSBNQ1AgbWVzc2FnZSBzaXplIGxpbWl0LlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYXJlYV91aV90eXBlIjp7ImVudW0iOlsiVklFV18zRCIsIklNQUdFX0VESVRPUiIsIlVWIiwiU2hhZGVyTm9kZVRyZWUiLCJDb21wb3NpdG9yTm9kZVRyZWUiLCJHZW9tZXRyeU5vZGVUcmVlIiwiVGV4dHVyZU5vZGVUcmVlIiwiU0VRVUVOQ0VfRURJVE9SIiwiQ0xJUF9FRElUT1IiLCJET1BFU0hFRVRfRURJVE9SIiwiR1JBUEhfRURJVE9SIiwiTkxBX0VESVRPUiIsIlRFWFRfRURJVE9SIiwiQ09OU09MRSIsIklORk8iLCJUT1BCQVIiLCJTVEFUVVNCQVIiLCJPVVRMSU5FUiIsIlBST1BFUlRJRVMiLCJGSUxFX0JST1dTRVIiLCJTUFJFQURTSEVFVCIsIlBSRUZFUkVOQ0VTIl0sInRpdGxlIjoiQXJlYSBVaSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJzaXplX2xpbWl0X2luX2J5dGVzIjp7ImRlZmF1bHQiOjAsInRpdGxlIjoiU2l6ZSBMaW1pdCBJbiBCeXRlcyIsInR5cGUiOiJpbnRlZ2VyIn19LCJyZXF1aXJlZCI6WyJhcmVhX3VpX3R5cGUiXSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb24iLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBKU09OIGRlc2NyaXB0aW9uIG9mIHRoZSBCbGVuZGVyIHdpbmRvdyBsYXlvdXQsIGFyZWFzLCBhY3RpdmUgb2JqZWN0LCBhbmQgc2VsZWN0aW9uLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0aGUgYWN0aXZlIHdvcmtzcGFjZSB0YWIgdG8gKm5hbWUqLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdG8gYSB3b3Jrc3BhY2Ugd2hvc2UgbWFpbiBhcmVhIG1hdGNoZXMgKnNwYWNlX3R5cGUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSBhbmQgbm8gbWF0Y2hpbmcgd29ya3NwYWNlIGV4aXN0cywgYSBuZXcgb25lXG4gICAgICAgIGlzIGNyZWF0ZWQgYnkgZHVwbGljYXRpbmcgdGhlIGN1cnJlbnQgd29ya3NwYWNlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsic3BhY2VfdHlwZSI6eyJ0aXRsZSI6IlNwYWNlIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbInNwYWNlX3R5cGUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byBmb2N1cyBvbiBhbiBvYmplY3QgYnkgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gdGhlIG9iamVjdCB3aG9zZSBkYXRhIGJsb2NrIG1hdGNoZXMgKm5hbWUqLlxuXG4gICAgICAgIElmICphbGxvd19lZGl0cyogaXMgVHJ1ZSB0aGUgb2JqZWN0IG1heSBiZSB1bi1oaWRkZW4gYW5kIGl0c1xuICAgICAgICBjb2xsZWN0aW9ucyBlbmFibGVkIHRvIG1ha2UgaXQgdmlzaWJsZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInRpdGxlIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciBhIHNtYWxsLCBsb3ctcXVhbGl0eSB0aHVtYm5haWwgdG8gKm91dHB1dF9wYXRoKiAodGVtcG9yYXJpbHkgb3ZlcnJpZGVzIHNldHRpbmdzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl90aHVtYm5haWxfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIHRvICpvdXRwdXRfcGF0aCogdXNpbmcgY3VycmVudCByZW5kZXIgc2V0dGluZ3MuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aEFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciBQeXRob24gQVBJIHJlZmVyZW5jZS5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX21hbnVhbF9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIHVzZXIgbWFudWFsLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfbWFudWFsX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fV19"}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:20:31 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301628-oRfjaCk3e23lNWYhqTjM", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca3b19590c7517-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301628-oRfjaCk3e23lNWYhqTjM\",\"object\":\"chat.completion\",\"created\":1784301628,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":\"The composition is looking good. Let me make some final adjustments: I want to ensure the table edge is visible in the lower frame, and that the objects are well-grouped with overlapping depth. Let me also add a few more details to sell the Dutch Golden Age look.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-880e723bea6f81d2\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# FINAL COMPOSITION ADJUSTMENTS\\\\n# ============================================================\\\\n\\\\n# Adjust camera to see table edge in lower frame and get better angle\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.0, -3.5, 1.8)\\\\ntarget = Vector((0.1, -0.1, 0.3))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\n# Adjust teapot position to be more centered and commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.0, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-15))\\\\nteapot.scale = (0.95, 0.95, 0.95)\\\\n\\\\n# Bunny slightly closer and turned toward camera\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.0, 0.2, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\\\\nbunny.scale = (1.15, 1.15, 1.15)\\\\n\\\\n# Suzanne on right, gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Sphere more centered, in front of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.2, -0.65, 0.22)\\\\n\\\\n# Wine glass moved slightly\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.65, 0.4, 0.0)\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\n\\\\n# Candlestick on left, behind bunny\\\\nstick = bpy.data.objects[\\\\\\\"Candlestick\\\\\\\"]\\\\nstick.location = (-1.7, 0.9, 0.0)\\\\ncandle = bpy.data.objects[\\\\\\\"Candle\\\\\\\"]\\\\ncandle.location = (-1.7, 0.9, 0.575)\\\\nflame = bpy.data.objects[\\\\\\\"CandleFlame\\\\\\\"]\\\\nflame.location = (-1.7, 0.9, 0.70)\\\\nflame_light = bpy.data.objects[\\\\\\\"CandleLight\\\\\\\"]\\\\nflame_light.location = (-1.7, 0.9, 0.72)\\\\n\\\\n# Book\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.4, -0.85, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(25))\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.8, -0.85, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.0, -0.75, 0.075)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.65, -0.7, 0.08)\\\\n\\\\nprint(\\\\\\\"Final composition adjustments made.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":52418,\"completion_tokens\":847,\"total_tokens\":53265,\"cost\":0.01166115168,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":52352,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.01166115168,\"upstream_inference_prompt_cost\":0.00916792248,\"upstream_inference_completions_cost\":0.0024932292},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTYyOC1vUmZqYUNrM2UyM2xOV1locVRqTSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDE2MjgsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgY29tcG9zaXRpb24gaXMgbG9va2luZyBnb29kLiBMZXQgbWUgbWFrZSBzb21lIGZpbmFsIGFkanVzdG1lbnRzOiBJIHdhbnQgdG8gZW5zdXJlIHRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgaW4gdGhlIGxvd2VyIGZyYW1lLCBhbmQgdGhhdCB0aGUgb2JqZWN0cyBhcmUgd2VsbC1ncm91cGVkIHdpdGggb3ZlcmxhcHBpbmcgZGVwdGguIExldCBtZSBhbHNvIGFkZCBhIGZldyBtb3JlIGRldGFpbHMgdG8gc2VsbCB0aGUgRHV0Y2ggR29sZGVuIEFnZSBsb29rLiIsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC04ODBlNzIzYmVhNmY4MWQyIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgRklOQUwgQ09NUE9TSVRJT04gQURKVVNUTUVOVFNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgQWRqdXN0IGNhbWVyYSB0byBzZWUgdGFibGUgZWRnZSBpbiBsb3dlciBmcmFtZSBhbmQgZ2V0IGJldHRlciBhbmdsZVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjAsIC0zLjUsIDEuOClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zKSlcXG5kaXJlY3Rpb24gPSB0YXJnZXQgLSBjYW0ubG9jYXRpb25cXG5yb3RfcXVhdCA9IGRpcmVjdGlvbi50b190cmFja19xdWF0KCctWicsICdZJylcXG5jYW0ucm90YXRpb25fZXVsZXIgPSByb3RfcXVhdC50b19ldWxlcigpXFxuY2FtLmRhdGEuZG9mLmZvY3VzX2Rpc3RhbmNlID0gKGNhbS5sb2NhdGlvbiAtIHRhcmdldCkubGVuZ3RoXFxuXFxuIyBBZGp1c3QgdGVhcG90IHBvc2l0aW9uIHRvIGJlIG1vcmUgY2VudGVyZWQgYW5kIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4wLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0xNSkpXFxudGVhcG90LnNjYWxlID0gKDAuOTUsIDAuOTUsIDAuOTUpXFxuXFxuIyBCdW5ueSBzbGlnaHRseSBjbG9zZXIgYW5kIHR1cm5lZCB0b3dhcmQgY2FtZXJhXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4wLCAwLjIsIDAuMDMpXFxuYnVubnkucm90YXRpb25fZXVsZXIgPSAoMCwgbWF0aC5yYWRpYW5zKDUpLCBtYXRoLnJhZGlhbnMoMzApKVxcbmJ1bm55LnNjYWxlID0gKDEuMTUsIDEuMTUsIDEuMTUpXFxuXFxuIyBTdXphbm5lIG9uIHJpZ2h0LCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4wLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoOCksIG1hdGgucmFkaWFucygtNSksIG1hdGgucmFkaWFucyg3MCkpXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjA0KVxcblxcbiMgU3BoZXJlIG1vcmUgY2VudGVyZWQsIGluIGZyb250IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMiwgLTAuNjUsIDAuMjIpXFxuXFxuIyBXaW5lIGdsYXNzIG1vdmVkIHNsaWdodGx5XFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNjUsIDAuNCwgMC4wKVxcbndpbmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lTGlxdWlkXFxcIl1cXG53aW5lLmxvY2F0aW9uID0gZ2xhc3MubG9jYXRpb24uY29weSgpXFxuXFxuIyBDYW5kbGVzdGljayBvbiBsZWZ0LCBiZWhpbmQgYnVubnlcXG5zdGljayA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbmRsZXN0aWNrXFxcIl1cXG5zdGljay5sb2NhdGlvbiA9ICgtMS43LCAwLjksIDAuMClcXG5jYW5kbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDYW5kbGVcXFwiXVxcbmNhbmRsZS5sb2NhdGlvbiA9ICgtMS43LCAwLjksIDAuNTc1KVxcbmZsYW1lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlRmxhbWVcXFwiXVxcbmZsYW1lLmxvY2F0aW9uID0gKC0xLjcsIDAuOSwgMC43MClcXG5mbGFtZV9saWdodCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbmRsZUxpZ2h0XFxcIl1cXG5mbGFtZV9saWdodC5sb2NhdGlvbiA9ICgtMS43LCAwLjksIDAuNzIpXFxuXFxuIyBCb29rXFxuYm9vayA9IGJweS5kYXRhLm9iamVjdHNbXFxcIk9wZW5Cb29rXFxcIl1cXG5ib29rLmxvY2F0aW9uID0gKC0wLjQsIC0wLjg1LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDI1KSlcXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0XFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOCwgLTAuODUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMCwgLTAuNzUsIDAuMDc1KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLmxvY2F0aW9uID0gKDAuNjUsIC0wLjcsIDAuMDgpXFxuXFxucHJpbnQoXFxcIkZpbmFsIGNvbXBvc2l0aW9uIGFkanVzdG1lbnRzIG1hZGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX19XSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6NTI0MTgsImNvbXBsZXRpb25fdG9rZW5zIjo4NDcsInRvdGFsX3Rva2VucyI6NTMyNjUsImNvc3QiOjAuMDExNjYxMTUxNjgsImlzX2J5b2siOmZhbHNlLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6NTIzNTIsImNhY2hlX3dyaXRlX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowLCJ2aWRlb190b2tlbnMiOjB9LCJjb3N0X2RldGFpbHMiOnsidXBzdHJlYW1faW5mZXJlbmNlX2Nvc3QiOjAuMDExNjYxMTUxNjgsInVwc3RyZWFtX2luZmVyZW5jZV9wcm9tcHRfY29zdCI6MC4wMDkxNjc5MjI0OCwidXBzdHJlYW1faW5mZXJlbmNlX2NvbXBsZXRpb25zX2Nvc3QiOjAuMDAyNDkzMjI5Mn0sImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOnsicmVhc29uaW5nX3Rva2VucyI6MCwiaW1hZ2VfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9fX0="}, "error": null}], "response": {"text": "The composition is looking good. Let me make some final adjustments: I want to ensure the table edge is visible in the lower frame, and that the objects are well-grouped with overlapping depth. Let me also add a few more details to sell the Dutch Golden Age look.", "tool_calls": [{"id": "chatcmpl-tool-880e723bea6f81d2", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# FINAL COMPOSITION ADJUSTMENTS\n# ============================================================\n\n# Adjust camera to see table edge in lower frame and get better angle\ncam = bpy.data.objects[\"Camera_Presentation\"]\ncam.location = (3.0, -3.5, 1.8)\ntarget = Vector((0.1, -0.1, 0.3))\ndirection = target - cam.location\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\ncam.data.dof.focus_distance = (cam.location - target).length\n\n# Adjust teapot position to be more centered and commanding\nteapot = bpy.data.objects[\"UtahTeapot\"]\nteapot.location = (0.0, 0.0, 0.0)\nteapot.rotation_euler = (0, 0, math.radians(-15))\nteapot.scale = (0.95, 0.95, 0.95)\n\n# Bunny slightly closer and turned toward camera\nbunny = bpy.data.objects[\"StanfordBunny\"]\nbunny.location = (-1.0, 0.2, 0.03)\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\nbunny.scale = (1.15, 1.15, 1.15)\n\n# Suzanne on right, gazing out\nsuzanne = bpy.data.objects[\"Suzanne\"]\nsuzanne.location = (1.0, -0.1, 0.2)\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\nbase = bpy.data.objects[\"SuzanneBase\"]\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\n\n# Sphere more centered, in front of teapot\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nsphere.location = (0.2, -0.65, 0.22)\n\n# Wine glass moved slightly\nglass = bpy.data.objects[\"WineGlass\"]\nglass.location = (1.65, 0.4, 0.0)\nwine = bpy.data.objects[\"WineLiquid\"]\nwine.location = glass.location.copy()\n\n# Candlestick on left, behind bunny\nstick = bpy.data.objects[\"Candlestick\"]\nstick.location = (-1.7, 0.9, 0.0)\ncandle = bpy.data.objects[\"Candle\"]\ncandle.location = (-1.7, 0.9, 0.575)\nflame = bpy.data.objects[\"CandleFlame\"]\nflame.location = (-1.7, 0.9, 0.70)\nflame_light = bpy.data.objects[\"CandleLight\"]\nflame_light.location = (-1.7, 0.9, 0.72)\n\n# Book\nbook = bpy.data.objects[\"OpenBook\"]\nbook.location = (-0.4, -0.85, 0.02)\nbook.rotation_euler = (0, 0, math.radians(25))\ncover = bpy.data.objects[\"BookCover\"]\ncover.location = book.location.copy()\ncover.rotation_euler = book.rotation_euler.copy()\n\n# Fruit\nbpy.data.objects[\"Orange1\"].location = (0.8, -0.85, 0.09)\nbpy.data.objects[\"Orange2\"].location = (1.0, -0.75, 0.075)\nbpy.data.objects[\"Lemon1\"].location = (0.65, -0.7, 0.08)\n\nprint(\"Final composition adjustments made.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# FINAL COMPOSITION ADJUSTMENTS\\n# ============================================================\\n\\n# Adjust camera to see table edge in lower frame and get better angle\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.0, -3.5, 1.8)\\ntarget = Vector((0.1, -0.1, 0.3))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\n# Adjust teapot position to be more centered and commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.0, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-15))\\nteapot.scale = (0.95, 0.95, 0.95)\\n\\n# Bunny slightly closer and turned toward camera\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.0, 0.2, 0.03)\\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\\nbunny.scale = (1.15, 1.15, 1.15)\\n\\n# Suzanne on right, gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Sphere more centered, in front of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.2, -0.65, 0.22)\\n\\n# Wine glass moved slightly\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.65, 0.4, 0.0)\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\n\\n# Candlestick on left, behind bunny\\nstick = bpy.data.objects[\\\"Candlestick\\\"]\\nstick.location = (-1.7, 0.9, 0.0)\\ncandle = bpy.data.objects[\\\"Candle\\\"]\\ncandle.location = (-1.7, 0.9, 0.575)\\nflame = bpy.data.objects[\\\"CandleFlame\\\"]\\nflame.location = (-1.7, 0.9, 0.70)\\nflame_light = bpy.data.objects[\\\"CandleLight\\\"]\\nflame_light.location = (-1.7, 0.9, 0.72)\\n\\n# Book\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.4, -0.85, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(25))\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.8, -0.85, 0.09)\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.0, -0.75, 0.075)\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.65, -0.7, 0.08)\\n\\nprint(\\\"Final composition adjustments made.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 52418, "tokens_out": 847, "cost_usd": 0.01166115168, "cached_tokens": 52352}, "error": null}
{"ts": "2026-07-17T15:20:49.473093+00:00", "type": "assistant", "text": "The composition is looking good. Let me make some final adjustments: I want to ensure the table edge is visible in the lower frame, and that the objects are well-grouped with overlapping depth. Let me also add a few more details to sell the Dutch Golden Age look.", "tool_calls": [{"id": "chatcmpl-tool-880e723bea6f81d2", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# FINAL COMPOSITION ADJUSTMENTS\n# ============================================================\n\n# Adjust camera to see table edge in lower frame and get better angle\ncam = bpy.data.objects[\"Camera_Presentation\"]\ncam.location = (3.0, -3.5, 1.8)\ntarget = Vector((0.1, -0.1, 0.3))\ndirection = target - cam.location\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\ncam.data.dof.focus_distance = (cam.location - target).length\n\n# Adjust teapot position to be more centered and commanding\nteapot = bpy.data.objects[\"UtahTeapot\"]\nteapot.location = (0.0, 0.0, 0.0)\nteapot.rotation_euler = (0, 0, math.radians(-15))\nteapot.scale = (0.95, 0.95, 0.95)\n\n# Bunny slightly closer and turned toward camera\nbunny = bpy.data.objects[\"StanfordBunny\"]\nbunny.location = (-1.0, 0.2, 0.03)\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\nbunny.scale = (1.15, 1.15, 1.15)\n\n# Suzanne on right, gazing out\nsuzanne = bpy.data.objects[\"Suzanne\"]\nsuzanne.location = (1.0, -0.1, 0.2)\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\nbase = bpy.data.objects[\"SuzanneBase\"]\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\n\n# Sphere more centered, in front of teapot\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nsphere.location = (0.2, -0.65, 0.22)\n\n# Wine glass moved slightly\nglass = bpy.data.objects[\"WineGlass\"]\nglass.location = (1.65, 0.4, 0.0)\nwine = bpy.data.objects[\"WineLiquid\"]\nwine.location = glass.location.copy()\n\n# Candlestick on left, behind bunny\nstick = bpy.data.objects[\"Candlestick\"]\nstick.location = (-1.7, 0.9, 0.0)\ncandle = bpy.data.objects[\"Candle\"]\ncandle.location = (-1.7, 0.9, 0.575)\nflame = bpy.data.objects[\"CandleFlame\"]\nflame.location = (-1.7, 0.9, 0.70)\nflame_light = bpy.data.objects[\"CandleLight\"]\nflame_light.location = (-1.7, 0.9, 0.72)\n\n# Book\nbook = bpy.data.objects[\"OpenBook\"]\nbook.location = (-0.4, -0.85, 0.02)\nbook.rotation_euler = (0, 0, math.radians(25))\ncover = bpy.data.objects[\"BookCover\"]\ncover.location = book.location.copy()\ncover.rotation_euler = book.rotation_euler.copy()\n\n# Fruit\nbpy.data.objects[\"Orange1\"].location = (0.8, -0.85, 0.09)\nbpy.data.objects[\"Orange2\"].location = (1.0, -0.75, 0.075)\nbpy.data.objects[\"Lemon1\"].location = (0.65, -0.7, 0.08)\n\nprint(\"Final composition adjustments made.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# FINAL COMPOSITION ADJUSTMENTS\\n# ============================================================\\n\\n# Adjust camera to see table edge in lower frame and get better angle\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.0, -3.5, 1.8)\\ntarget = Vector((0.1, -0.1, 0.3))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\n# Adjust teapot position to be more centered and commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.0, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-15))\\nteapot.scale = (0.95, 0.95, 0.95)\\n\\n# Bunny slightly closer and turned toward camera\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.0, 0.2, 0.03)\\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\\nbunny.scale = (1.15, 1.15, 1.15)\\n\\n# Suzanne on right, gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Sphere more centered, in front of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.2, -0.65, 0.22)\\n\\n# Wine glass moved slightly\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.65, 0.4, 0.0)\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\n\\n# Candlestick on left, behind bunny\\nstick = bpy.data.objects[\\\"Candlestick\\\"]\\nstick.location = (-1.7, 0.9, 0.0)\\ncandle = bpy.data.objects[\\\"Candle\\\"]\\ncandle.location = (-1.7, 0.9, 0.575)\\nflame = bpy.data.objects[\\\"CandleFlame\\\"]\\nflame.location = (-1.7, 0.9, 0.70)\\nflame_light = bpy.data.objects[\\\"CandleLight\\\"]\\nflame_light.location = (-1.7, 0.9, 0.72)\\n\\n# Book\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.4, -0.85, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(25))\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.8, -0.85, 0.09)\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.0, -0.75, 0.075)\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.65, -0.7, 0.08)\\n\\nprint(\\\"Final composition adjustments made.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:20:49.473093+00:00", "type": "tool_call", "id": "chatcmpl-tool-880e723bea6f81d2", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\nimport math\nfrom mathutils import Vector\n\n# ============================================================\n# FINAL COMPOSITION ADJUSTMENTS\n# ============================================================\n\n# Adjust camera to see table edge in lower frame and get better angle\ncam = bpy.data.objects[\"Camera_Presentation\"]\ncam.location = (3.0, -3.5, 1.8)\ntarget = Vector((0.1, -0.1, 0.3))\ndirection = target - cam.location\nrot_quat = direction.to_track_quat('-Z', 'Y')\ncam.rotation_euler = rot_quat.to_euler()\ncam.data.dof.focus_distance = (cam.location - target).length\n\n# Adjust teapot position to be more centered and commanding\nteapot = bpy.data.objects[\"UtahTeapot\"]\nteapot.location = (0.0, 0.0, 0.0)\nteapot.rotation_euler = (0, 0, math.radians(-15))\nteapot.scale = (0.95, 0.95, 0.95)\n\n# Bunny slightly closer and turned toward camera\nbunny = bpy.data.objects[\"StanfordBunny\"]\nbunny.location = (-1.0, 0.2, 0.03)\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\nbunny.scale = (1.15, 1.15, 1.15)\n\n# Suzanne on right, gazing out\nsuzanne = bpy.data.objects[\"Suzanne\"]\nsuzanne.location = (1.0, -0.1, 0.2)\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\nbase = bpy.data.objects[\"SuzanneBase\"]\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\n\n# Sphere more centered, in front of teapot\nsphere = bpy.data.objects[\"CheckeredSphere\"]\nsphere.location = (0.2, -0.65, 0.22)\n\n# Wine glass moved slightly\nglass = bpy.data.objects[\"WineGlass\"]\nglass.location = (1.65, 0.4, 0.0)\nwine = bpy.data.objects[\"WineLiquid\"]\nwine.location = glass.location.copy()\n\n# Candlestick on left, behind bunny\nstick = bpy.data.objects[\"Candlestick\"]\nstick.location = (-1.7, 0.9, 0.0)\ncandle = bpy.data.objects[\"Candle\"]\ncandle.location = (-1.7, 0.9, 0.575)\nflame = bpy.data.objects[\"CandleFlame\"]\nflame.location = (-1.7, 0.9, 0.70)\nflame_light = bpy.data.objects[\"CandleLight\"]\nflame_light.location = (-1.7, 0.9, 0.72)\n\n# Book\nbook = bpy.data.objects[\"OpenBook\"]\nbook.location = (-0.4, -0.85, 0.02)\nbook.rotation_euler = (0, 0, math.radians(25))\ncover = bpy.data.objects[\"BookCover\"]\ncover.location = book.location.copy()\ncover.rotation_euler = book.rotation_euler.copy()\n\n# Fruit\nbpy.data.objects[\"Orange1\"].location = (0.8, -0.85, 0.09)\nbpy.data.objects[\"Orange2\"].location = (1.0, -0.75, 0.075)\nbpy.data.objects[\"Lemon1\"].location = (0.65, -0.7, 0.08)\n\nprint(\"Final composition adjustments made.\")\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# FINAL COMPOSITION ADJUSTMENTS\\n# ============================================================\\n\\n# Adjust camera to see table edge in lower frame and get better angle\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.0, -3.5, 1.8)\\ntarget = Vector((0.1, -0.1, 0.3))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\n# Adjust teapot position to be more centered and commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.0, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-15))\\nteapot.scale = (0.95, 0.95, 0.95)\\n\\n# Bunny slightly closer and turned toward camera\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.0, 0.2, 0.03)\\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\\nbunny.scale = (1.15, 1.15, 1.15)\\n\\n# Suzanne on right, gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Sphere more centered, in front of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.2, -0.65, 0.22)\\n\\n# Wine glass moved slightly\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.65, 0.4, 0.0)\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\n\\n# Candlestick on left, behind bunny\\nstick = bpy.data.objects[\\\"Candlestick\\\"]\\nstick.location = (-1.7, 0.9, 0.0)\\ncandle = bpy.data.objects[\\\"Candle\\\"]\\ncandle.location = (-1.7, 0.9, 0.575)\\nflame = bpy.data.objects[\\\"CandleFlame\\\"]\\nflame.location = (-1.7, 0.9, 0.70)\\nflame_light = bpy.data.objects[\\\"CandleLight\\\"]\\nflame_light.location = (-1.7, 0.9, 0.72)\\n\\n# Book\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.4, -0.85, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(25))\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.8, -0.85, 0.09)\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.0, -0.75, 0.075)\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.65, -0.7, 0.08)\\n\\nprint(\\\"Final composition adjustments made.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:20:49.946984+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-880e723bea6f81d2", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Final composition adjustments made.\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:21:04.403912+00:00", "type": "llm_call", "call_index": 69, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:20:49.981573+00:00", "finished_at": "2026-07-17T15:21:04.403912+00:00", "duration_s": 14.421000000002095, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}"}, {"role": "assistant", "content": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a1bde82900051568", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▒ ● ·             |\\n  Row 4: |█ ▒ ● ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8bf5081c37eebeb6", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8bf5081c37eebeb6", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-96f3c02259f22638", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check the right side of the image for green\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed color check on the right portion\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    if brightness < 0.05:\\n        continue\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check the right side specifically\\nright_g = 0\\nright_t = 0\\nfor y in range(h):\\n    for x in range(int(w*0.7), w, 3):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_t += 1\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\n                right_g += 1\\nprint(f\\\"Right side green: {100*right_g/right_t:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-96f3c02259f22638", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\nRight side green: 10.8%\\n\"\n}"}, {"role": "assistant", "content": "Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.", "tool_calls": [{"id": "chatcmpl-tool-99ced8845b19cf57", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# CANDLESTICK with candle - additional classical prop\\n# Justifies the warm light source\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"CandlestickMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the candlestick (radius, height) — lathed\\nstick_profile = [\\n    (0.00, 0.00),    # center bottom\\n    (0.12, 0.00),    # base edge\\n    (0.13, 0.01),    # base lip\\n    (0.12, 0.03),    # \\n    (0.08, 0.04),    # base to stem\\n    (0.05, 0.06),    # stem base\\n    (0.04, 0.15),    # stem\\n    (0.04, 0.25),    # stem\\n    (0.05, 0.30),    # mid decorative\\n    (0.04, 0.35),    # \\n    (0.035, 0.40),   # upper stem\\n    (0.05, 0.44),    # candle cup base\\n    (0.06, 0.46),    # cup\\n    (0.055, 0.48),   # cup lip\\n    (0.04, 0.50),    # cup inner\\n    (0.00, 0.50),    # center top\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in stick_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = stick_profile[ri]\\n    rb, _ = stick_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nstick_obj = bpy.data.objects.new(\\\"Candlestick\\\", mesh)\\nlink_obj(stick_obj)\\nstick_obj.location = (-1.6, 0.8, 0.0)\\nbpy.context.view_layer.objects.active = stick_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = stick_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# Candle\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\ncandle = bpy.context.active_object\\ncandle.name = \\\"Candle\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Candle flame - a small emissive shape\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\nflame = bpy.context.active_object\\nflame.name = \\\"CandleFlame\\\"\\nflame.scale = (0.6, 0.6, 1.8)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\nbpy.ops.object.shade_smooth()\\n\\nprint(\\\"Candlestick with candle and flame built.\\\")\\nresult = {\\\"candlestick\\\": stick_obj.name, \\\"candle\\\": candle.name, \\\"flame\\\": flame.name}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-99ced8845b19cf57", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"candlestick\": \"Candlestick\",\n    \"candle\": \"Candle\",\n    \"flame\": \"CandleFlame\"\n  },\n  \"stdout\": \"Candlestick with candle and flame built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-86253733bb060d5b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- Candlestick: Aged brass/bronze ---\\nmat, nt = create_material(\\\"M_CandlestickBrass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 5.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 40.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Candlestick\\\"].data.materials.append(mat)\\n\\n# --- Candle: Waxed off-white ---\\nmat, nt = create_material(\\\"M_Candle\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.5\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Candle\\\"].data.materials.append(mat)\\n\\n# --- Candle flame: Emissive ---\\nmat, nt = create_material(\\\"M_CandleFlame\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\nemission.inputs['Strength'].default_value = 15.0\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\nbpy.data.objects[\\\"CandleFlame\\\"].data.materials.append(mat)\\n\\n# Add a point light at the flame for actual illumination\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\nflame_light = bpy.context.active_object\\nflame_light.name = \\\"CandleLight\\\"\\nflame_light.data.energy = 50\\nflame_light.data.color = (1.0, 0.7, 0.3)\\nflame_light.data.shadow_soft_size = 0.05\\n\\nprint(\\\"Candlestick, candle, and flame materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-86253733bb060d5b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Candlestick, candle, and flame materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad276f7e043b8f86", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render with candle\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview8.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview8.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad276f7e043b8f86", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▓ ● ·             |\\n  Row 4: |▒ ▒ ▓ ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ ▒ ▓ ▓ ○ •   |\\n  Row 7: |● █ █ █ ▒ ▒ ▒ ▒ ▓ ▓ |\\n  Row 8: |█ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 9: |▒ █ █ █ █ █ █ ▒ ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ac68c75cb6cd7431", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac68c75cb6cd7431", "content": ""}, {"role": "assistant", "content": "The composition is looking good. Let me make some final adjustments: I want to ensure the table edge is visible in the lower frame, and that the objects are well-grouped with overlapping depth. Let me also add a few more details to sell the Dutch Golden Age look.", "tool_calls": [{"id": "chatcmpl-tool-880e723bea6f81d2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# FINAL COMPOSITION ADJUSTMENTS\\n# ============================================================\\n\\n# Adjust camera to see table edge in lower frame and get better angle\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.0, -3.5, 1.8)\\ntarget = Vector((0.1, -0.1, 0.3))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\n# Adjust teapot position to be more centered and commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.0, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-15))\\nteapot.scale = (0.95, 0.95, 0.95)\\n\\n# Bunny slightly closer and turned toward camera\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.0, 0.2, 0.03)\\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\\nbunny.scale = (1.15, 1.15, 1.15)\\n\\n# Suzanne on right, gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Sphere more centered, in front of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.2, -0.65, 0.22)\\n\\n# Wine glass moved slightly\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.65, 0.4, 0.0)\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\n\\n# Candlestick on left, behind bunny\\nstick = bpy.data.objects[\\\"Candlestick\\\"]\\nstick.location = (-1.7, 0.9, 0.0)\\ncandle = bpy.data.objects[\\\"Candle\\\"]\\ncandle.location = (-1.7, 0.9, 0.575)\\nflame = bpy.data.objects[\\\"CandleFlame\\\"]\\nflame.location = (-1.7, 0.9, 0.70)\\nflame_light = bpy.data.objects[\\\"CandleLight\\\"]\\nflame_light.location = (-1.7, 0.9, 0.72)\\n\\n# Book\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.4, -0.85, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(25))\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.8, -0.85, 0.09)\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.0, -0.75, 0.075)\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.65, -0.7, 0.08)\\n\\nprint(\\\"Final composition adjustments made.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-880e723bea6f81d2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Final composition adjustments made.\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:20:49.981573+00:00", "finished_at": "2026-07-17T15:21:04.402921+00:00", "duration_s": 14.421000000002095, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "200176", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9cddced158a16a7f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Connected bump to BSDF Normal\\\\nConnected BSDF to output\\\\n\\\\nFinal links:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n  Bump.Normal -> Principled BSDF.Normal\\\\n  Principled BSDF.BSDF -> Material Output.Surface\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good, Suzanne material is fixed. Now let me render to check everything looks good.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a1bde82900051568\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a1bde82900051568\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▒ ● ·             |\\\\n  Row 4: |█ ▒ ● ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-96f3c02259f22638\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check the right side of the image for green\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed color check on the right portion\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    if brightness < 0.05:\\\\n        continue\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check the right side specifically\\\\nright_g = 0\\\\nright_t = 0\\\\nfor y in range(h):\\\\n    for x in range(int(w*0.7), w, 3):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_t += 1\\\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\\\n                right_g += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_g/right_t:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-96f3c02259f22638\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\\\nRight side green: 10.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-99ced8845b19cf57\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# CANDLESTICK with candle - additional classical prop\\\\n# Justifies the warm light source\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"CandlestickMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the candlestick (radius, height) — lathed\\\\nstick_profile = [\\\\n    (0.00, 0.00),    # center bottom\\\\n    (0.12, 0.00),    # base edge\\\\n    (0.13, 0.01),    # base lip\\\\n    (0.12, 0.03),    # \\\\n    (0.08, 0.04),    # base to stem\\\\n    (0.05, 0.06),    # stem base\\\\n    (0.04, 0.15),    # stem\\\\n    (0.04, 0.25),    # stem\\\\n    (0.05, 0.30),    # mid decorative\\\\n    (0.04, 0.35),    # \\\\n    (0.035, 0.40),   # upper stem\\\\n    (0.05, 0.44),    # candle cup base\\\\n    (0.06, 0.46),    # cup\\\\n    (0.055, 0.48),   # cup lip\\\\n    (0.04, 0.50),    # cup inner\\\\n    (0.00, 0.50),    # center top\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in stick_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = stick_profile[ri]\\\\n    rb, _ = stick_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nstick_obj = bpy.data.objects.new(\\\\\\\"Candlestick\\\\\\\", mesh)\\\\nlink_obj(stick_obj)\\\\nstick_obj.location = (-1.6, 0.8, 0.0)\\\\nbpy.context.view_layer.objects.active = stick_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = stick_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# Candle\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\\\ncandle = bpy.context.active_object\\\\ncandle.name = \\\\\\\"Candle\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Candle flame - a small emissive shape\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\\\nflame = bpy.context.active_object\\\\nflame.name = \\\\\\\"CandleFlame\\\\\\\"\\\\nflame.scale = (0.6, 0.6, 1.8)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nprint(\\\\\\\"Candlestick with candle and flame built.\\\\\\\")\\\\nresult = {\\\\\\\"candlestick\\\\\\\": stick_obj.name, \\\\\\\"candle\\\\\\\": candle.name, \\\\\\\"flame\\\\\\\": flame.name}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-99ced8845b19cf57\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"candlestick\\\": \\\"Candlestick\\\",\\n    \\\"candle\\\": \\\"Candle\\\",\\n    \\\"flame\\\": \\\"CandleFlame\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick with candle and flame built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-86253733bb060d5b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- Candlestick: Aged brass/bronze ---\\\\nmat, nt = create_material(\\\\\\\"M_CandlestickBrass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 5.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 40.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Candlestick\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle: Waxed off-white ---\\\\nmat, nt = create_material(\\\\\\\"M_Candle\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.5\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Candle\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle flame: Emissive ---\\\\nmat, nt = create_material(\\\\\\\"M_CandleFlame\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\\\nemission.inputs['Strength'].default_value = 15.0\\\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"CandleFlame\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Add a point light at the flame for actual illumination\\\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\\\nflame_light = bpy.context.active_object\\\\nflame_light.name = \\\\\\\"CandleLight\\\\\\\"\\\\nflame_light.data.energy = 50\\\\nflame_light.data.color = (1.0, 0.7, 0.3)\\\\nflame_light.data.shadow_soft_size = 0.05\\\\n\\\\nprint(\\\\\\\"Candlestick, candle, and flame materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-86253733bb060d5b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick, candle, and flame materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad276f7e043b8f86\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render with candle\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview8.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview8.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad276f7e043b8f86\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▓ ● ·             |\\\\n  Row 4: |▒ ▒ ▓ ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ ▒ ▓ ▓ ○ •   |\\\\n  Row 7: |● █ █ █ ▒ ▒ ▒ ▒ ▓ ▓ |\\\\n  Row 8: |█ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 9: |▒ █ █ █ █ █ █ ▒ ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac68c75cb6cd7431\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac68c75cb6cd7431\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good. Let me make some final adjustments: I want to ensure the table edge is visible in the lower frame, and that the objects are well-grouped with overlapping depth. Let me also add a few more details to sell the Dutch Golden Age look.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-880e723bea6f81d2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# FINAL COMPOSITION ADJUSTMENTS\\\\n# ============================================================\\\\n\\\\n# Adjust camera to see table edge in lower frame and get better angle\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.0, -3.5, 1.8)\\\\ntarget = Vector((0.1, -0.1, 0.3))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\n# Adjust teapot position to be more centered and commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.0, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-15))\\\\nteapot.scale = (0.95, 0.95, 0.95)\\\\n\\\\n# Bunny slightly closer and turned toward camera\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.0, 0.2, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\\\\nbunny.scale = (1.15, 1.15, 1.15)\\\\n\\\\n# Suzanne on right, gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Sphere more centered, in front of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.2, -0.65, 0.22)\\\\n\\\\n# Wine glass moved slightly\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.65, 0.4, 0.0)\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\n\\\\n# Candlestick on left, behind bunny\\\\nstick = bpy.data.objects[\\\\\\\"Candlestick\\\\\\\"]\\\\nstick.location = (-1.7, 0.9, 0.0)\\\\ncandle = bpy.data.objects[\\\\\\\"Candle\\\\\\\"]\\\\ncandle.location = (-1.7, 0.9, 0.575)\\\\nflame = bpy.data.objects[\\\\\\\"CandleFlame\\\\\\\"]\\\\nflame.location = (-1.7, 0.9, 0.70)\\\\nflame_light = bpy.data.objects[\\\\\\\"CandleLight\\\\\\\"]\\\\nflame_light.location = (-1.7, 0.9, 0.72)\\\\n\\\\n# Book\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.4, -0.85, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(25))\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.8, -0.85, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.0, -0.75, 0.075)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.65, -0.7, 0.08)\\\\n\\\\nprint(\\\\\\\"Final composition adjustments made.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-880e723bea6f81d2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Final composition adjustments made.\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWNkZGNlZDE1OGExNmE3ZiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBDb25uZWN0IGJ1bXAgdG8gQlNERiBOb3JtYWwgYW5kIEJTREYgdG8gb3V0cHV0XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5cXG4jIE1ha2Ugc3VyZSBidW1wIG5vcm1hbCBnb2VzIHRvIEJTREZcXG5idW1wID0gTm9uZVxcbmJzZGYgPSBOb25lXFxub3V0cHV0ID0gTm9uZVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ0JVTVAnOlxcbiAgICAgICAgYnVtcCA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ0JTREZfUFJJTkNJUExFRCc6XFxuICAgICAgICBic2RmID0gbm9kZVxcbiAgICBlbGlmIG5vZGUudHlwZSA9PSAnT1VUUFVUX01BVEVSSUFMJzpcXG4gICAgICAgIG91dHB1dCA9IG5vZGVcXG5cXG5pZiBidW1wIGFuZCBic2RmOlxcbiAgICBudC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXFwiKVxcblxcbmlmIGJzZGYgYW5kIG91dHB1dDpcXG4gICAgbnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuICAgIHByaW50KFxcXCJDb25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXFwiKVxcblxcbnByaW50KFxcXCJcXFxcbkZpbmFsIGxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05Y2RkY2VkMTU4YTE2YTdmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXG5Db25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXG5cXG5GaW5hbCBsaW5rczpcXG4gIFRleHR1cmUgQ29vcmRpbmF0ZS5HZW5lcmF0ZWQgLT4gTWFwcGluZy5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IE5vaXNlIFRleHR1cmUuVmVjdG9yXFxuICBNYXBwaW5nLlZlY3RvciAtPiBXYXZlIFRleHR1cmUuVmVjdG9yXFxuICBXYXZlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkFcXG4gIE5vaXNlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkJcXG4gIE1peC5SZXN1bHQgLT4gQ29sb3IgUmFtcC5GYWN0b3JcXG4gIENvbG9yIFJhbXAuQ29sb3IgLT4gUHJpbmNpcGxlZCBCU0RGLkJhc2UgQ29sb3JcXG4gIE5vaXNlIFRleHR1cmUuMDAxLkZhY3RvciAtPiBCdW1wLkhlaWdodFxcbiAgQnVtcC5Ob3JtYWwgLT4gUHJpbmNpcGxlZCBCU0RGLk5vcm1hbFxcbiAgUHJpbmNpcGxlZCBCU0RGLkJTREYgLT4gTWF0ZXJpYWwgT3V0cHV0LlN1cmZhY2VcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kLCBTdXphbm5lIG1hdGVyaWFsIGlzIGZpeGVkLiBOb3cgbGV0IG1lIHJlbmRlciB0byBjaGVjayBldmVyeXRoaW5nIGxvb2tzIGdvb2QuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWExYmRlODI5MDAwNTE1NjgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc3LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTFiZGU4MjkwMDA1MTU2OCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8ICDCtyDCtyAgICAgICAgIMK3IMK3IMK3IHxcXG4gIFJvdyAxOiB84oCiIMK3ICAgICDCtyDigKIg4oCiIMK3IMK3ICAgfFxcbiAgUm93IDI6IHzCtyDigKIg4peLIOKAoiDCtyAgICAgICAgICAgfFxcbiAgUm93IDM6IHzilpMg4paSIOKXjyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNDogfOKWiCDilpIg4pePIMK3ICAgICAgICAgICAgIHxcXG4gIFJvdyA1OiB84paTIOKXjyDilpMg4pePIOKXjyDCtyAgICAgICAgIHxcXG4gIFJvdyA2OiB8ICDil48g4paSIOKWkiDilogg4paSIOKWkyDil4sg4oCiICAgfFxcbiAgUm93IDc6IHzil4sg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDg6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paSIOKWkiDilpIgfFxcbiAgUm93IDk6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLThiZjUwODFjMzdlZWJlYjYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04YmY1MDgxYzM3ZWViZWI2IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIG9mIHRoZSBpbWFnZSBmb3IgZ3JlZW5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgRGV0YWlsZWQgY29sb3IgY2hlY2sgb24gdGhlIHJpZ2h0IHBvcnRpb25cXG5yZWRfY291bnQgPSAwXFxuZ3JlZW5fY291bnQgPSAwXFxud2FybV9jb3VudCA9IDBcXG50b3RhbCA9IDBcXG5cXG5mb3IgaSBpbiByYW5nZSgwLCBsZW4ocGl4ZWxzKSwgNCk6XFxuICAgIHIsIGcsIGIgPSBwaXhlbHNbaV0sIHBpeGVsc1tpKzFdLCBwaXhlbHNbaSsyXVxcbiAgICB0b3RhbCArPSAxXFxuICAgIGJyaWdodG5lc3MgPSAociArIGcgKyBiKSAvIDNcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgZWxpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgIGVsaWYgciA+IDAuMiBhbmQgZyA+IDAuMTUgYW5kIHIgPiBiICogMS4zOlxcbiAgICAgICAgd2FybV9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJSZWQ6IHsxMDAqcmVkX2NvdW50L3RvdGFsOi4xZn0lLCBHcmVlbjogezEwMCpncmVlbl9jb3VudC90b3RhbDouMWZ9JSwgV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIHNwZWNpZmljYWxseVxcbnJpZ2h0X2cgPSAwXFxucmlnaHRfdCA9IDBcXG5mb3IgeSBpbiByYW5nZShoKTpcXG4gICAgZm9yIHggaW4gcmFuZ2UoaW50KHcqMC43KSwgdywgMyk6XFxuICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICByLCBnLCBiID0gcGl4ZWxzW2lkeF0sIHBpeGVsc1tpZHgrMV0sIHBpeGVsc1tpZHgrMl1cXG4gICAgICAgICAgICByaWdodF90ICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4wOCBhbmQgZyA+IHIgKiAxLjE1IGFuZCBnID4gYiAqIDEuMTU6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2cgKz0gMVxcbnByaW50KGZcXFwiUmlnaHQgc2lkZSBncmVlbjogezEwMCpyaWdodF9nL3JpZ2h0X3Q6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkOiAxNC4wJSwgR3JlZW46IDMuOCUsIFdhcm06IDMxLjQlXFxuUmlnaHQgc2lkZSBncmVlbjogMTAuOCVcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kIC0gZ3JlZW4gaXMgbm93IHZpc2libGUgb24gdGhlIHJpZ2h0IHNpZGUuIFRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgd2l0aCByZWQgb24gdGhlIGxlZnQsIGdyZWVuIG9uIHRoZSByaWdodCAoQ29ybmVsbCBib3ggcGFsZXR0ZSksIHdhcm0gbGlnaHQsIGFuZCBkYXJrIHNoYWRvd3MuIExldCBtZSBub3cgYWRkIHNvbWUgZmluYWwgcG9saXNoOiBhIGNhbmRsZXN0aWNrIGFzIGFuIGFkZGl0aW9uYWwgY2xhc3NpY2FsIHByb3AgKHdoaWNoIGFsc28ganVzdGlmaWVzIHRoZSB3YXJtIGxpZ2h0IHNvdXJjZSksIGFuZCBtYWtlIGFkanVzdG1lbnRzIHRvIHRoZSBTdXphbm5lIGJ1c3QgcG9zaXRpb25pbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk5Y2VkODg0NWIxOWNmNTciLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ0FORExFU1RJQ0sgd2l0aCBjYW5kbGUgLSBhZGRpdGlvbmFsIGNsYXNzaWNhbCBwcm9wXFxuIyBKdXN0aWZpZXMgdGhlIHdhcm0gbGlnaHQgc291cmNlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQ2FuZGxlc3RpY2tNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSBjYW5kbGVzdGljayAocmFkaXVzLCBoZWlnaHQpIOKAlCBsYXRoZWRcXG5zdGlja19wcm9maWxlID0gW1xcbiAgICAoMC4wMCwgMC4wMCksICAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4xMiwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjEzLCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMiwgMC4wMyksICAgICMgXFxuICAgICgwLjA4LCAwLjA0KSwgICAgIyBiYXNlIHRvIHN0ZW1cXG4gICAgKDAuMDUsIDAuMDYpLCAgICAjIHN0ZW0gYmFzZVxcbiAgICAoMC4wNCwgMC4xNSksICAgICMgc3RlbVxcbiAgICAoMC4wNCwgMC4yNSksICAgICMgc3RlbVxcbiAgICAoMC4wNSwgMC4zMCksICAgICMgbWlkIGRlY29yYXRpdmVcXG4gICAgKDAuMDQsIDAuMzUpLCAgICAjIFxcbiAgICAoMC4wMzUsIDAuNDApLCAgICMgdXBwZXIgc3RlbVxcbiAgICAoMC4wNSwgMC40NCksICAgICMgY2FuZGxlIGN1cCBiYXNlXFxuICAgICgwLjA2LCAwLjQ2KSwgICAgIyBjdXBcXG4gICAgKDAuMDU1LCAwLjQ4KSwgICAjIGN1cCBsaXBcXG4gICAgKDAuMDQsIDAuNTApLCAgICAjIGN1cCBpbm5lclxcbiAgICAoMC4wMCwgMC41MCksICAgICMgY2VudGVyIHRvcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBzdGlja19wcm9maWxlOlxcbiAgICByaW5nID0gW11cXG4gICAgaWYgciA8IDAuMDAxOlxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4oYWxsX3ZlcnRzKSAtIDEpOlxcbiAgICByaW5nX2EgPSBhbGxfdmVydHNbcmldXFxuICAgIHJpbmdfYiA9IGFsbF92ZXJ0c1tyaSArIDFdXFxuICAgIHJhLCBfID0gc3RpY2tfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBzdGlja19wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuc3RpY2tfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkNhbmRsZXN0aWNrXFxcIiwgbWVzaClcXG5saW5rX29iaihzdGlja19vYmopXFxuc3RpY2tfb2JqLmxvY2F0aW9uID0gKC0xLjYsIDAuOCwgMC4wKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBzdGlja19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IHN0aWNrX29iai5tb2RpZmllcnMubmV3KFxcXCJTdWJzdXJmXFxcIiwgJ1NVQlNVUkYnKVxcbm1vZC5sZXZlbHMgPSAxXFxubW9kLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuIyBDYW5kbGVcXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX2N5bGluZGVyX2FkZChyYWRpdXM9MC4wMzUsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgtMS42LCAwLjgsIDAuNTc1KSlcXG5jYW5kbGUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuY2FuZGxlLm5hbWUgPSBcXFwiQ2FuZGxlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBDYW5kbGUgZmxhbWUgLSBhIHNtYWxsIGVtaXNzaXZlIHNoYXBlXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz0wLjAzLCBzZWdtZW50cz0xNiwgcmluZ19jb3VudD04LCBsb2NhdGlvbj0oLTEuNiwgMC44LCAwLjcwKSlcXG5mbGFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5mbGFtZS5uYW1lID0gXFxcIkNhbmRsZUZsYW1lXFxcIlxcbmZsYW1lLnNjYWxlID0gKDAuNiwgMC42LCAxLjgpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1GYWxzZSwgc2NhbGU9VHJ1ZSlcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbnByaW50KFxcXCJDYW5kbGVzdGljayB3aXRoIGNhbmRsZSBhbmQgZmxhbWUgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNhbmRsZXN0aWNrXFxcIjogc3RpY2tfb2JqLm5hbWUsIFxcXCJjYW5kbGVcXFwiOiBjYW5kbGUubmFtZSwgXFxcImZsYW1lXFxcIjogZmxhbWUubmFtZX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05OWNlZDg4NDViMTljZjU3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjYW5kbGVzdGlja1wiOiBcIkNhbmRsZXN0aWNrXCIsXG4gICAgXCJjYW5kbGVcIjogXCJDYW5kbGVcIixcbiAgICBcImZsYW1lXCI6IFwiQ2FuZGxlRmxhbWVcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbmRsZXN0aWNrIHdpdGggY2FuZGxlIGFuZCBmbGFtZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NjI1MzczM2JiMDYwZDViIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIENhbmRsZXN0aWNrOiBBZ2VkIGJyYXNzL2Jyb256ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZXN0aWNrQnJhc3NcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDIsIDAuMjAsIDEuMCkgICMgYnJhc3NcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjM1XFxuXFxuIyBQYXRpbmEgdmFyaWF0aW9uXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNS4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MiwgMC4yMCwgMS4wKSAgIyBicmFzc1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjM1LCAwLjIwLCAxLjApICAjIHBhdGluYVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkNhbmRsZXN0aWNrXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGU6IFdheGVkIG9mZi13aGl0ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MiwgMC43MiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGUgZmxhbWU6IEVtaXNzaXZlIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQ2FuZGxlRmxhbWVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuZW1pc3Npb24gPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVFbWlzc2lvbicsICgyMDAsIDApKVxcbmVtaXNzaW9uLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDEuMCwgMC43LCAwLjMsIDEuMCkgICMgd2FybSBmbGFtZVxcbmVtaXNzaW9uLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm50LmxpbmtzLm5ldyhlbWlzc2lvbi5vdXRwdXRzWydFbWlzc2lvbiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlRmxhbWVcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgQWRkIGEgcG9pbnQgbGlnaHQgYXQgdGhlIGZsYW1lIGZvciBhY3R1YWwgaWxsdW1pbmF0aW9uXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J1BPSU5UJywgbG9jYXRpb249KC0xLjYsIDAuOCwgMC43MikpXFxuZmxhbWVfbGlnaHQgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxhbWVfbGlnaHQubmFtZSA9IFxcXCJDYW5kbGVMaWdodFxcXCJcXG5mbGFtZV9saWdodC5kYXRhLmVuZXJneSA9IDUwXFxuZmxhbWVfbGlnaHQuZGF0YS5jb2xvciA9ICgxLjAsIDAuNywgMC4zKVxcbmZsYW1lX2xpZ2h0LmRhdGEuc2hhZG93X3NvZnRfc2l6ZSA9IDAuMDVcXG5cXG5wcmludChcXFwiQ2FuZGxlc3RpY2ssIGNhbmRsZSwgYW5kIGZsYW1lIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2MjUzNzMzYmIwNjBkNWIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJDYW5kbGVzdGljaywgY2FuZGxlLCBhbmQgZmxhbWUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWQyNzZmN2UwNDNiOGY4NiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBSZW5kZXIgd2l0aCBjYW5kbGVcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3OC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc4LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDEweDEwIGdyaWQpOlxcXCIpXFxuZm9yIGd5IGluIHJhbmdlKDEwKTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDEwKTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDEwXFxuICAgICAgICB4MiA9IChneCsxKSAqIHcgLy8gMTBcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDEwXFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gMTBcXG4gICAgICAgIGJyaWdodF9zdW0gPSAwXFxuICAgICAgICBjb3VudCA9IDBcXG4gICAgICAgIGZvciB5IGluIHJhbmdlKHkxLCB5MiwgMjUpOlxcbiAgICAgICAgICAgIGZvciB4IGluIHJhbmdlKHgxLCB4MiwgMjUpOlxcbiAgICAgICAgICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgICAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgICAgICAgICAgYnJpZ2h0X3N1bSArPSAocGl4ZWxzW2lkeF0gKyBwaXhlbHNbaWR4KzFdICsgcGl4ZWxzW2lkeCsyXSkgLyAzXFxuICAgICAgICAgICAgICAgICAgICBjb3VudCArPSAxXFxuICAgICAgICBicmlnaHQgPSBicmlnaHRfc3VtIC8gY291bnQgaWYgY291bnQgPiAwIGVsc2UgMFxcbiAgICAgICAgaWYgYnJpZ2h0IDwgMC4wNjogcm93ICs9IFxcXCIgIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4xMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40OiByb3cgKz0gXFxcIuKXjyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNTU6IHJvdyArPSBcXFwi4paTIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC43OiByb3cgKz0gXFxcIuKWkiBcXFwiXFxuICAgICAgICBlbHNlOiByb3cgKz0gXFxcIuKWiCBcXFwiXFxuICAgIHByaW50KGZcXFwiICBSb3cge2d5fTogfHtyb3d9fFxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFkMjc2ZjdlMDQzYjhmODYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxuICBSb3cgMDogfCAgwrcgwrcgICAgICAgICDCtyDCtyDCtyB8XFxuICBSb3cgMTogfOKAoiDCtyAgICAgwrcg4oCiIOKAoiDCtyDCtyAgIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXiyDigKIgwrcgICAgICAgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkyDil48gwrcgICAgICAgICAgICAgfFxcbiAgUm93IDQ6IHzilpIg4paSIOKWkyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNTogfOKWkyDil48g4paTIOKXjyDil48gwrcgICAgICAgICB8XFxuICBSb3cgNjogfCAg4pePIOKWkiDilpIg4paSIOKWkyDilpMg4peLIOKAoiAgIHxcXG4gIFJvdyA3OiB84pePIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMg4paTIHxcXG4gIFJvdyA4OiB84paIIOKWiCDilogg4paIIOKWiCDilpIg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA5OiB84paSIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paTIHxcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hYzY4Yzc1Y2I2Y2Q3NDMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWM2OGM3NWNiNmNkNzQzMSIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIGNvbXBvc2l0aW9uIGlzIGxvb2tpbmcgZ29vZC4gTGV0IG1lIG1ha2Ugc29tZSBmaW5hbCBhZGp1c3RtZW50czogSSB3YW50IHRvIGVuc3VyZSB0aGUgdGFibGUgZWRnZSBpcyB2aXNpYmxlIGluIHRoZSBsb3dlciBmcmFtZSwgYW5kIHRoYXQgdGhlIG9iamVjdHMgYXJlIHdlbGwtZ3JvdXBlZCB3aXRoIG92ZXJsYXBwaW5nIGRlcHRoLiBMZXQgbWUgYWxzbyBhZGQgYSBmZXcgbW9yZSBkZXRhaWxzIHRvIHNlbGwgdGhlIER1dGNoIEdvbGRlbiBBZ2UgbG9vay4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwZTcyM2JlYTZmODFkMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIEZJTkFMIENPTVBPU0lUSU9OIEFESlVTVE1FTlRTXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIEFkanVzdCBjYW1lcmEgdG8gc2VlIHRhYmxlIGVkZ2UgaW4gbG93ZXIgZnJhbWUgYW5kIGdldCBiZXR0ZXIgYW5nbGVcXG5jYW0gPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDYW1lcmFfUHJlc2VudGF0aW9uXFxcIl1cXG5jYW0ubG9jYXRpb24gPSAoMy4wLCAtMy41LCAxLjgpXFxudGFyZ2V0ID0gVmVjdG9yKCgwLjEsIC0wLjEsIDAuMykpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbiMgQWRqdXN0IHRlYXBvdCBwb3NpdGlvbiB0byBiZSBtb3JlIGNlbnRlcmVkIGFuZCBjb21tYW5kaW5nXFxudGVhcG90ID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiVXRhaFRlYXBvdFxcXCJdXFxudGVhcG90LmxvY2F0aW9uID0gKDAuMCwgMC4wLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjk1LCAwLjk1LCAwLjk1KVxcblxcbiMgQnVubnkgc2xpZ2h0bHkgY2xvc2VyIGFuZCB0dXJuZWQgdG93YXJkIGNhbWVyYVxcbmJ1bm55ID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiU3RhbmZvcmRCdW5ueVxcXCJdXFxuYnVubnkubG9jYXRpb24gPSAoLTEuMCwgMC4yLCAwLjAzKVxcbmJ1bm55LnJvdGF0aW9uX2V1bGVyID0gKDAsIG1hdGgucmFkaWFucyg1KSwgbWF0aC5yYWRpYW5zKDMwKSlcXG5idW5ueS5zY2FsZSA9ICgxLjE1LCAxLjE1LCAxLjE1KVxcblxcbiMgU3V6YW5uZSBvbiByaWdodCwgZ2F6aW5nIG91dFxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMSwgMC4yKVxcbnN1emFubmUucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDgpLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzApKVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIFNwaGVyZSBtb3JlIGNlbnRlcmVkLCBpbiBmcm9udCBvZiB0ZWFwb3RcXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbnNwaGVyZS5sb2NhdGlvbiA9ICgwLjIsIC0wLjY1LCAwLjIyKVxcblxcbiMgV2luZSBnbGFzcyBtb3ZlZCBzbGlnaHRseVxcbmdsYXNzID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl1cXG5nbGFzcy5sb2NhdGlvbiA9ICgxLjY1LCAwLjQsIDAuMClcXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcblxcbiMgQ2FuZGxlc3RpY2sgb24gbGVmdCwgYmVoaW5kIGJ1bm55XFxuc3RpY2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDYW5kbGVzdGlja1xcXCJdXFxuc3RpY2subG9jYXRpb24gPSAoLTEuNywgMC45LCAwLjApXFxuY2FuZGxlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlXFxcIl1cXG5jYW5kbGUubG9jYXRpb24gPSAoLTEuNywgMC45LCAwLjU3NSlcXG5mbGFtZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbmRsZUZsYW1lXFxcIl1cXG5mbGFtZS5sb2NhdGlvbiA9ICgtMS43LCAwLjksIDAuNzApXFxuZmxhbWVfbGlnaHQgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDYW5kbGVMaWdodFxcXCJdXFxuZmxhbWVfbGlnaHQubG9jYXRpb24gPSAoLTEuNywgMC45LCAwLjcyKVxcblxcbiMgQm9va1xcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC40LCAtMC44NSwgMC4wMilcXG5ib29rLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygyNSkpXFxuY292ZXIgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJCb29rQ292ZXJcXFwiXVxcbmNvdmVyLmxvY2F0aW9uID0gYm9vay5sb2NhdGlvbi5jb3B5KClcXG5jb3Zlci5yb3RhdGlvbl9ldWxlciA9IGJvb2sucm90YXRpb25fZXVsZXIuY29weSgpXFxuXFxuIyBGcnVpdFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIk9yYW5nZTFcXFwiXS5sb2NhdGlvbiA9ICgwLjgsIC0wLjg1LCAwLjA5KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIk9yYW5nZTJcXFwiXS5sb2NhdGlvbiA9ICgxLjAsIC0wLjc1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjY1LCAtMC43LCAwLjA4KVxcblxcbnByaW50KFxcXCJGaW5hbCBjb21wb3NpdGlvbiBhZGp1c3RtZW50cyBtYWRlLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg4MGU3MjNiZWE2ZjgxZDIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaW5hbCBjb21wb3NpdGlvbiBhZGp1c3RtZW50cyBtYWRlLlxcblwiXG59In1dLCJ1c2FnZSI6eyJpbmNsdWRlIjp0cnVlfSwidG9vbHMiOlt7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEV4ZWN1dGUgUHl0aG9uIGNvZGUgaW4gdGhlIGNvbm5lY3RlZCBCbGVuZGVyIGluc3RhbmNlLlxuXG4gICAgICAgIFRoZSBjb2RlIHJ1bnMgaW4gQmxlbmRlcidzIFB5dGhvbiBlbnZpcm9ubWVudCB3aXRoIGZ1bGwgYWNjZXNzIHRvIGBgYnB5YGAuXG4gICAgICAgIFRvIHJldHVybiBkYXRhLCBhc3NpZ24gYSBKU09OLXNlcmlhbGlzYWJsZSBkaWN0IHRvIGEgdmFyaWFibGUgbmFtZWQgYGByZXN1bHRgYC5cbiAgICAgICAgRGVmZXJyZWQgY29tcGxldGlvbiB2aWEgYGBjaGVja19pc19maW5pc2hlZGBgIGlzIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZVxuICAgICAgICBpbnRlcmFjdGl2ZSBhZGRvbiBzZXJ2ZXIsIGFuZCBpcyByZWplY3RlZCBpbiBiYWNrZ3JvdW5kIG1vZGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIGEgYmFja2dyb3VuZCBCbGVuZGVyIHByb2Nlc3MuXG5cbiAgICAgICAgT3BlbnMgKmJsZW5kX2ZpbGUqIHdpdGggYGBibGVuZGVyIC0tYmFja2dyb3VuZGBgIGFuZCBydW5zICpjb2RlKi5cbiAgICAgICAgQXNzaWduIGEgZGljdCB0byBgYHJlc3VsdGBgIHRvIHJldHVybiBkYXRhLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn0sImNvZGUiOnsidGl0bGUiOiJDb2RlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSIsImNvZGUiXSwidGl0bGUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSBzdW1tYXJ5IG9mIHRoZSBibGVuZCBmaWxlOiBkYXRhLWJsb2NrIGNvdW50cywgYWN0aXZlIHdvcmtzcGFjZSwgYW5kIHJlbmRlciBlbmdpbmUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgZGF0YS1ibG9jayBzdW1tYXJ5IGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBleHRlcm5hbCBmaWxlIHJlZmVyZW5jZXMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGRpc2tcbiAgICAgICAgKGltYWdlcywgbGlicmFyaWVzLCBmb250cywgc291bmRzLCBtb3ZpZSBjbGlwcywgY2FjaGVzLCBzZXF1ZW5jZXMpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlcG9ydCBtaXNzaW5nIGZpbGUgcmVmZXJlbmNlcyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gYSB0cmVlIG9mIGRpcmVjdGx5IGFuZCBpbmRpcmVjdGx5IGxpbmtlZCBsaWJyYXJ5IGZpbGVzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X29mX2xpbmtlZF9saWJyYXJpZXNfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBsaW5rZWQtbGlicmFyeSBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU2ltcGxlL2Zhc3QgYWNjZXNzIHRvIHRoZSBibGVuZCBmaWxlJ3MgcGF0aCwgc2F2ZSBzdGF0dXMsIGFnZSwgYW5kIGJhY2t1cHMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBwYXRoIGluZm8gYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mb19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdGhlIHByaW1hcnkgdXNlLWNhc2VzIG9mIHRoZSBjdXJyZW50IGJsZW5kIGZpbGUgKHNjb3JlZCAwLTEwMCB3aXRoIGNlcnRhaW50eSkuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBHdWVzcyB1c2UtY2FzZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3VzYWdlX2d1ZXNzX2Zvcl9jbGlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3RydWN0dXJlZCBzdW1tYXJ5IG9mIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieSAqbmFtZSouXG5cbiAgICAgICAgSW5jbHVkZXMgdHlwZSwgdHJhbnNmb3JtcywgcGFyZW50LCBjaGlsZHJlbiwgbW9kaWZpZXJzLCBjb25zdHJhaW50cyxcbiAgICAgICAgbWF0ZXJpYWxzLCB2aXNpYmlsaXR5LCBkYXRhLWJsb2NrIG5hbWUsIGFuZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6ImdldF9vYmplY3RfZGV0YWlsX3N1bW1hcnlBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5IiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIHRoZSBzY2VuZSdzIGNvbGxlY3Rpb24gaGllcmFyY2h5IGFuZCB0aGVpciBvYmplY3RzLlxuXG4gICAgICAgIEVhY2ggY29sbGVjdGlvbiBsaXN0cyBpdHMgb2JqZWN0cyAobmFtZSwgdHlwZSwgcGFyZW50LCBkYXRhIG5hbWUsXG4gICAgICAgIHNlbGVjdGlvbiwgdmlzaWJpbGl0eSkgYW5kIG5lc3RlZCBjaGlsZCBjb2xsZWN0aW9ucy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfb2JqZWN0c19zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3B5dGhvbl9hcGlfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgQmxlbmRlciBQeXRob24gQVBJIGRvY3MgZm9yICppZGVudGlmaWVyKiwgb3IgbGlzdFxuICAgICAgICBtb2R1bGVzIG1hdGNoaW5nIGEgdHJhaWxpbmctYGAqYGAgZGlzY292ZXJ5IHBhdHRlcm4uXG5cbiAgICAgICAgKmlkZW50aWZpZXIqIHNob3VsZCBiZSBhIGZ1bGx5LXF1YWxpZmllZCBQeXRob24gbmFtZSAoZS5nLlxuICAgICAgICBgYGJweS5hcHBgYCBvciBgYGJweS50eXBlcy5TY2VuZS5mcmFtZV9jdXJyZW50YGApLlxuICAgICAgICBUaGUgdHJhaWxpbmctYGAqYGAgZm9ybXMgYXJlIHN1cHBvcnRlZCBhcyBkaXNjb3ZlcnkgZW50cnktcG9pbnRzOlxuXG4gICAgICAgIC0gYGAqYGAgZW51bWVyYXRlcyB0aGUgdG9wLWxldmVsIG1vZHVsZXMgKGBgYnB5YGAsIGBgYm1lc2hgYCxcbiAgICAgICAgICBgYG1hdGh1dGlsc2BgLCBgYGdwdWBgLCAuLi4pLlxuICAgICAgICAtIGBgWC4qYGAgZW51bWVyYXRlcyB0aGUgZGlyZWN0LWNoaWxkIGlkZW50aWZpZXJzIHVuZGVyIHRoZVxuICAgICAgICAgICpYKiBuYW1lc3BhY2UgKGBgYnB5LipgYCAtPiBgYGJweS5hcHBgYCwgYGBicHkuY29udGV4dGBgLCAuLi4pLlxuXG4gICAgICAgIEJvdGggcmV0dXJuIGEgYGBuYW1lc3BhY2VgYCByZXNwb25zZSBldmVuIHdoZW4gYGBYLnJzdGBgIHdvdWxkXG4gICAgICAgIG90aGVyd2lzZSByZXNvbHZlIHRvIGBgZXhhY3RgYDsgdGhlIGBgLipgYCBmb3JtIGxldHMgYW4gYWdlbnRcbiAgICAgICAgZm9yY2UgdGhlIGNoaWxkIGxpc3RpbmcuXG5cbiAgICAgICAgVGhlIHJlc3BvbnNlIGFsd2F5cyBjYXJyaWVzIGBga2luZGBgLCBgYGZvdW5kYGAsIGFuZCBgYGlkZW50aWZpZXJgYC5cbiAgICAgICAgVGhlIHJlbWFpbmluZyBrZXlzIGRlcGVuZCBvbiBgYGtpbmRgYDpcblxuICAgICAgICAtIGBgXCJleGFjdFwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTogYGA8aWRlbnRpZmllcj4ucnN0YGAgd2FzIHJlYWQuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKFJTVCB0ZXh0KSwgYGBleGFtcGxlc2BgLiBXaGVuIHRoZVxuICAgICAgICAgIGZpbGUgZXhjZWVkcyAzMiBLQiwgYGBjb250ZW50YGAgaXMgcmVwbGFjZWQgd2l0aCBhIGRvdC1wb2ludFxuICAgICAgICAgIHN1bW1hcnkgb2YgdGhlIGZpbGUncyB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgKHByZWZpeGVkIGJ5IGFcbiAgICAgICAgICBoZWFkZXIgbm90aW5nIHRoZSB0cnVuY2F0aW9uKSBhbmQgYGBleGFtcGxlc2BgIGlzIGVtcHR5IC1cbiAgICAgICAgICByZS1xdWVyeSBpbmRpdmlkdWFsIG1lbWJlcnMgZm9yIHRoZWlyIHJlbmRlcmVkIGJsb2Nrcy5cbiAgICAgICAgLSBgYFwibmFtZXNwYWNlXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgIG5vIGBgPGlkZW50aWZpZXI+LnJzdGBgIGJ1dCBgYDxpZGVudGlmaWVyPi48Y2hpbGQ+LnJzdGBgIHNpYmxpbmdzIGV4aXN0LlxuICAgICAgICAgIEV4dHJhIGtleTogYGBzdWJtb2R1bGVzYGAgKGxpc3Qgb2YgY2hpbGQgaWRlbnRpZmllcnMpLlxuICAgICAgICAtIGBgXCJkZWZpbml0aW9uXCJgYCAoYGBmb3VuZD1UcnVlYGApOlxuICAgICAgICAgICppZGVudGlmaWVyKiBpcyBkZWZpbmVkIGluc2lkZSBhIHBhcmVudCBSU1RcbiAgICAgICAgICAoZS5nLiBgYGJweS5wcm9wcy5JbnRQcm9wZXJ0eWBgIGxpdmVzIGluIGBgYnB5LnByb3BzLnJzdGBgKS5cbiAgICAgICAgICBFeHRyYSBrZXlzOiBgYGNvbnRlbnRgYCAocmVuZGVyZWQgYmxvY2spLCBgYGV4YW1wbGVzYGAuXG4gICAgICAgIC0gYGBcInBhcnRpYWxcImBgIChgYGZvdW5kPUZhbHNlYGApOlxuICAgICAgICAgIHRoZSBwYXJlbnQgUlNUIHdhcyBsb2NhdGVkIGJ1dCB0aGUgdHJhaWxpbmcgY29tcG9uZW50IGlzbid0IGRlZmluZWQgaW4gaXQuXG4gICAgICAgICAgRXh0cmEga2V5czpcbiAgICAgICAgICAtIGBgcGFyZW50YGAgdGhlIGlkZW50aWZpZXIgd2hvc2UgUlNUIHdhcyBsb2FkZWQuXG4gICAgICAgICAgLSBgYGF2YWlsYWJsZWBgIHRvcC1sZXZlbCBkZWZpbml0aW9ucyBpbiB0aGF0IFJTVC5cbiAgICAgICAgICAtIGBgc3VibW9kdWxlc2BgIHNpYmxpbmcgaWRlbnRpZmllcnMgYGA8cGFyZW50Pi48Y2hpbGQ+YGAgd2l0aCB0aGVpciBvd24gUlNUcyxcbiAgICAgICAgICAgIGZpbHRlcmVkIHRvIHRob3NlIHdob3NlIGxhc3QgY29tcG9uZW50IGNvbnRhaW5zIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgbWlzc2luZyB0YWlsLlxuXG4gICAgICAgICAgRm9yIGEgdG9jdHJlZSBsYW5kaW5nIHBhZ2UgbGlrZSBgYGJweS50eXBlc2BgIGBgYXZhaWxhYmxlYGAgaXMgZW1wdHkgYW5kIGBgc3VibW9kdWxlc2BgXG4gICAgICAgICAgaXMgdGhlIG5lYXItbWlzcyBsaXN0OyBmb3IgYSBzZWxmLWNvbnRhaW5lZCBtb2R1bGUgbGlrZSBgYGJweS5wcm9wc2BgIGl0J3MgdGhlIHJldmVyc2UuXG4gICAgICAgIC0gYGBcInN1Z2dlc3Rpb25zXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICBubyBkaXJlY3QgbWF0Y2gsIGJ1dCAqaWRlbnRpZmllciogYXBwZWFycyBhcyBhIGNvbXBvbmVudCBvZiBvdGhlciBmaWxlcy5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VnZ2VzdGlvbnNgYCAobGlzdCBvZiBmdWxsIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwibWlzc2luZ1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6IG5vdGhpbmcgbWF0Y2hlZC5cblxuICAgICAgICBgYGV4YW1wbGVzYGAgKHByZXNlbnQgb24gdGhlIGBgZXhhY3RgYCBhbmQgYGBkZWZpbml0aW9uYGAga2luZHMpXG4gICAgICAgIGlzIGEgbGlzdCBvZiBgYHtwYXRoLCBjb250ZW50fWBgIGVudHJpZXMgcmVmZXJlbmNlZCBmcm9tIHRoaXMgZG9jdW1lbnRhdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImlkZW50aWZpZXIiOnsidGl0bGUiOiJJZGVudGlmaWVyIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiaWRlbnRpZmllciJdLCJ0aXRsZSI6ImdldF9weXRob25fYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgVGFrZSBhIHNjcmVlbnNob3Qgb2YgYSBzaW5nbGUgQmxlbmRlciBhcmVhIGFuZCByZXR1cm4gaXQgYXMgYSBQTkcgaW1hZ2UuXG5cbiAgICAgICAgKmFyZWFfdWlfdHlwZSogbWF0Y2hlcyB0aGUgYXJlYSdzIGBgdWlfdHlwZWBgLlxuXG4gICAgICAgICpzaXplX2xpbWl0X2luX2J5dGVzKiBjYXBzIHRoZSBpbWFnZSBzaXplIGluIGJ5dGVzLlxuICAgICAgICBaZXJvICh0aGUgZGVmYXVsdCkgdXNlcyB0aGUgTUNQIG1lc3NhZ2Ugc2l6ZSBsaW1pdC5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImFyZWFfdWlfdHlwZSI6eyJlbnVtIjpbIlZJRVdfM0QiLCJJTUFHRV9FRElUT1IiLCJVViIsIlNoYWRlck5vZGVUcmVlIiwiQ29tcG9zaXRvck5vZGVUcmVlIiwiR2VvbWV0cnlOb2RlVHJlZSIsIlRleHR1cmVOb2RlVHJlZSIsIlNFUVVFTkNFX0VESVRPUiIsIkNMSVBfRURJVE9SIiwiRE9QRVNIRUVUX0VESVRPUiIsIkdSQVBIX0VESVRPUiIsIk5MQV9FRElUT1IiLCJURVhUX0VESVRPUiIsIkNPTlNPTEUiLCJJTkZPIiwiVE9QQkFSIiwiU1RBVFVTQkFSIiwiT1VUTElORVIiLCJQUk9QRVJUSUVTIiwiRklMRV9CUk9XU0VSIiwiU1BSRUFEU0hFRVQiLCJQUkVGRVJFTkNFUyJdLCJ0aXRsZSI6IkFyZWEgVWkgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwic2l6ZV9saW1pdF9pbl9ieXRlcyI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IlNpemUgTGltaXQgSW4gQnl0ZXMiLCJ0eXBlIjoiaW50ZWdlciJ9fSwicmVxdWlyZWQiOlsiYXJlYV91aV90eXBlIl0sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX3dpbmRvd19hc19qc29uIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgSlNPTiBkZXNjcmlwdGlvbiBvZiB0aGUgQmxlbmRlciB3aW5kb3cgbGF5b3V0LCBhcmVhcywgYWN0aXZlIG9iamVjdCwgYW5kIHNlbGVjdGlvbi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbkFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdGFiX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBTd2l0Y2ggdGhlIGFjdGl2ZSB3b3Jrc3BhY2UgdGFiIHRvICpuYW1lKi5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsidGl0bGUiOiJOYW1lIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9zcGFjZV90eXBlIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRvIGEgd29ya3NwYWNlIHdob3NlIG1haW4gYXJlYSBtYXRjaGVzICpzcGFjZV90eXBlKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgYW5kIG5vIG1hdGNoaW5nIHdvcmtzcGFjZSBleGlzdHMsIGEgbmV3IG9uZVxuICAgICAgICBpcyBjcmVhdGVkIGJ5IGR1cGxpY2F0aW5nIHRoZSBjdXJyZW50IHdvcmtzcGFjZS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InNwYWNlX3R5cGUiOnsidGl0bGUiOiJTcGFjZSBUeXBlIiwidHlwZSI6InN0cmluZyJ9LCJhbGxvd19lZGl0cyI6eyJkZWZhdWx0IjpmYWxzZSwidGl0bGUiOiJBbGxvdyBFZGl0cyIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJzcGFjZV90eXBlIl0sInRpdGxlIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgTW92ZSB0aGUgM0Qgdmlld3BvcnQgdG8gZm9jdXMgb24gYW4gb2JqZWN0IGJ5ICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b192aWV3M2Rfb2JqZWN0X2RhdGFfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIHRoZSBvYmplY3Qgd2hvc2UgZGF0YSBibG9jayBtYXRjaGVzICpuYW1lKi5cblxuICAgICAgICBJZiAqYWxsb3dfZWRpdHMqIGlzIFRydWUgdGhlIG9iamVjdCBtYXkgYmUgdW4taGlkZGVuIGFuZCBpdHNcbiAgICAgICAgY29sbGVjdGlvbnMgZW5hYmxlZCB0byBtYWtlIGl0IHZpc2libGUuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgYSBzbWFsbCwgbG93LXF1YWxpdHkgdGh1bWJuYWlsIHRvICpvdXRwdXRfcGF0aCogKHRlbXBvcmFyaWx5IG92ZXJyaWRlcyBzZXR0aW5ncykuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJvdXRwdXRfcGF0aCI6eyJ0aXRsZSI6Ik91dHB1dCBQYXRoIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsib3V0cHV0X3BhdGgiXSwidGl0bGUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdmlld3BvcnRfdG9fcGF0aCIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJlbmRlciB0aGUgY3VycmVudCBzY2VuZSB0byAqb3V0cHV0X3BhdGgqIHVzaW5nIGN1cnJlbnQgcmVuZGVyIHNldHRpbmdzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGhBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgUHl0aG9uIEFQSSByZWZlcmVuY2UuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9hcGlfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6InNlYXJjaF9tYW51YWxfZG9jcyIsImRlc2NyaXB0aW9uIjoiXG5GdWxsLXRleHQgc2VhcmNoIG92ZXIgdGhlIGJ1bmRsZWQgQmxlbmRlciB1c2VyIG1hbnVhbC5cblxuUmV0dXJucyBhIHJhbmtlZCBsaXN0IG9mIGhpdHMuIEVhY2ggaGl0IGhhczpcblxuLSBgYHBhdGhgYDogZmlsZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBidW5kbGVkIGRvY3MuXG4tIGBgdGV4dGBgOiB0aGUgbWF0Y2hpbmcgcGFyYWdyYXBoIHBsdXMgYGBjb250ZXh0YGBcbiAgcGFyYWdyYXBocyBvbiBlaXRoZXIgc2lkZS5cbi0gYGBicmVhZGNydW1iYGA6IHRoZSBzZWN0aW9uIHBhdGggY29udGFpbmluZyB0aGUgaGl0XG4gIChgYFNlY3Rpb24gPiBTdWItc2VjdGlvbiA+IC4uLmBgKS5cbi0gYGBpbmRleGBgOiB0aGUgaGl0J3MgcG9zaXRpb24gaW4gdGhlIHJlc3VsdCBsaXN0LlxuLSBgYHNjb3JlYGA6IGEgcmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgYmV0dGVyLlxuXG5UaGUgcXVlcnkgaXMgdG9rZW5pc2VkIG9uIHdoaXRlc3BhY2UgYW5kIG1hdGNoZWRcbmNhc2UtaW5zZW5zaXRpdmVseS4gRXZlcnkgdG9rZW4gbXVzdCBhcHBlYXIgc29tZXdoZXJlIGluXG50aGUgcGFyYWdyYXBoIGJvZHksIHRoZSBmaWxlIHBhdGgsIG9yIGFuIGVuY2xvc2luZyBzZWN0aW9uXG50aXRsZSAtIGluIGFueSBvcmRlci4gQ29tbW9uIEVuZ2xpc2ggc3RvcC13b3JkcyAoYGB0aGVgYCxcbmBgYWBgLCBgYGhvd2BgLCBgYHRvYGAsIC4uLikgYXJlIGRyb3BwZWQsIHNvIG5hdHVyYWxcbnBocmFzaW5ncyBsaWtlIGBgXCJob3cgdG8gYmFrZVwiYGAgd29yayBhcyBleHBlY3RlZC4gUmVndWxhclxuZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cblVzZSBgYGNvbnRleHRgYCB0byBwdWxsIG1vcmUgc3Vycm91bmRpbmcgcGFyYWdyYXBocyBpbnRvXG5lYWNoIGhpdCAoc3ltbWV0cmljLCBkZWZhdWx0IDApLiBVc2UgYGBpbmRleGBgIHdpdGggdGhlXG5wb3NpdGlvbiBvZiBhIHByZXZpb3VzIGhpdCAoc2FtZSBxdWVyeSkgdG8gZ2V0IHRoYXQgaGl0XG5hbG9uZSB3aXRoIGl0cyB0ZXh0IHdpZGVuZWQgdG8gaXRzIGVuY2xvc2luZyBzZWN0aW9uLlxuXG5SZWFkLW9ubHk7IGNvbnN1bHRzIGJ1bmRsZWQgUlNUIGZpbGVzIG9ubHkuXG4iLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsicXVlcnkiOnsidGl0bGUiOiJRdWVyeSIsInR5cGUiOiJzdHJpbmcifSwibWF4X3Jlc3VsdHMiOnsiZGVmYXVsdCI6MjAsInRpdGxlIjoiTWF4IFJlc3VsdHMiLCJ0eXBlIjoiaW50ZWdlciJ9LCJjb250ZXh0Ijp7ImRlZmF1bHQiOjAsInRpdGxlIjoiQ29udGV4dCIsInR5cGUiOiJpbnRlZ2VyIn0sImluZGV4Ijp7ImFueU9mIjpbeyJ0eXBlIjoiaW50ZWdlciJ9LHsidHlwZSI6Im51bGwifV0sImRlZmF1bHQiOm51bGwsInRpdGxlIjoiSW5kZXgifX0sInJlcXVpcmVkIjpbInF1ZXJ5Il0sInRpdGxlIjoic2VhcmNoX21hbnVhbF9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX1dfQ=="}, "response": {"status_code": 200, "headers": {"date": "Fri, 17 Jul 2026 15:20:54 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "x-generation-id": "gen-1784301651-sQZsFNhKjUKocTWTA0sp", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca3ba70f9603fe-MAD"}, "body": "\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n\n         \n{\"id\":\"gen-1784301651-sQZsFNhKjUKocTWTA0sp\",\"object\":\"chat.completion\",\"created\":1784301651,\"model\":\"z-ai/glm-5.2\",\"provider\":\"Novita\",\"system_fingerprint\":null,\"service_tier\":null,\"choices\":[{\"index\":0,\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"message\":{\"role\":\"assistant\",\"content\":null,\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"id\":\"chatcmpl-tool-9ab206cfd8c4ba5d\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview9.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview9.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (12x12 grid):\\\\\\\")\\\\nfor gy in range(12):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(12):\\\\n        x1 = gx * w // 12\\\\n        x2 = (gx+1) * w // 12\\\\n        y1 = gy * h // 12\\\\n        y2 = (gy+1) * h // 12\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 30):\\\\n            for x in range(x1, x2, 30):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":53304,\"completion_tokens\":423,\"total_tokens\":53727,\"cost\":0.01119408264,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":52416,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.01119408264,\"upstream_inference_prompt_cost\":0.00994893984,\"upstream_inference_completions_cost\":0.0012451428},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}", "body_base64": "CiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCgogICAgICAgICAKCiAgICAgICAgIAoKICAgICAgICAgCnsiaWQiOiJnZW4tMTc4NDMwMTY1MS1zUVpzRk5oS2pVS29jVFdUQTBzcCIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbiIsImNyZWF0ZWQiOjE3ODQzMDE2NTEsIm1vZGVsIjoiei1haS9nbG0tNS4yIiwicHJvdmlkZXIiOiJOb3ZpdGEiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOm51bGwsInNlcnZpY2VfdGllciI6bnVsbCwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm5hdGl2ZV9maW5pc2hfcmVhc29uIjoidG9vbF9jYWxscyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInJlZnVzYWwiOm51bGwsInJlYXNvbmluZyI6bnVsbCwidG9vbF9jYWxscyI6W3sidHlwZSI6ImZ1bmN0aW9uIiwiaW5kZXgiOjAsImlkIjoiY2hhdGNtcGwtdG9vbC05YWIyMDZjZmQ4YzRiYTVkIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3XFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMzJcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzkucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3OS5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxucHJpbnQoXFxcIkJyaWdodG5lc3MgbWFwICgxMngxMiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSgxMik6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSgxMik6XFxuICAgICAgICB4MSA9IGd4ICogdyAvLyAxMlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDEyXFxuICAgICAgICB5MSA9IGd5ICogaCAvLyAxMlxcbiAgICAgICAgeTIgPSAoZ3krMSkgKiBoIC8vIDEyXFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDMwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDMwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDY6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTI6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI6IHJvdyArPSBcXFwi4oCiIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4zOiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfX1dLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjo1MzMwNCwiY29tcGxldGlvbl90b2tlbnMiOjQyMywidG90YWxfdG9rZW5zIjo1MzcyNywiY29zdCI6MC4wMTExOTQwODI2NCwiaXNfYnlvayI6ZmFsc2UsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjo1MjQxNiwiY2FjaGVfd3JpdGVfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsInZpZGVvX3Rva2VucyI6MH0sImNvc3RfZGV0YWlscyI6eyJ1cHN0cmVhbV9pbmZlcmVuY2VfY29zdCI6MC4wMTExOTQwODI2NCwidXBzdHJlYW1faW5mZXJlbmNlX3Byb21wdF9jb3N0IjowLjAwOTk0ODkzOTg0LCJ1cHN0cmVhbV9pbmZlcmVuY2VfY29tcGxldGlvbnNfY29zdCI6MC4wMDEyNDUxNDI4fSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJpbWFnZV90b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MH19fQ=="}, "error": null}], "response": {"text": null, "tool_calls": [{"id": "chatcmpl-tool-9ab206cfd8c4ba5d", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Render preview\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview9.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview9.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (12x12 grid):\")\nfor gy in range(12):\n    row = \"\"\n    for gx in range(12):\n        x1 = gx * w // 12\n        x2 = (gx+1) * w // 12\n        y1 = gy * h // 12\n        y2 = (gy+1) * h // 12\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 30):\n            for x in range(x1, x2, 30):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview9.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview9.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (12x12 grid):\\\")\\nfor gy in range(12):\\n    row = \\\"\\\"\\n    for gx in range(12):\\n        x1 = gx * w // 12\\n        x2 = (gx+1) * w // 12\\n        y1 = gy * h // 12\\n        y2 = (gy+1) * h // 12\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 30):\\n            for x in range(x1, x2, 30):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}], "tokens_in": 53304, "tokens_out": 423, "cost_usd": 0.01119408264, "cached_tokens": 52416}, "error": null}
{"ts": "2026-07-17T15:21:04.409942+00:00", "type": "assistant", "text": null, "tool_calls": [{"id": "chatcmpl-tool-9ab206cfd8c4ba5d", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Render preview\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview9.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview9.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (12x12 grid):\")\nfor gy in range(12):\n    row = \"\"\n    for gx in range(12):\n        x1 = gx * w // 12\n        x2 = (gx+1) * w // 12\n        y1 = gy * h // 12\n        y2 = (gy+1) * h // 12\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 30):\n            for x in range(x1, x2, 30):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview9.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview9.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (12x12 grid):\\\")\\nfor gy in range(12):\\n    row = \\\"\\\"\\n    for gx in range(12):\\n        x1 = gx * w // 12\\n        x2 = (gx+1) * w // 12\\n        y1 = gy * h // 12\\n        y2 = (gy+1) * h // 12\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 30):\\n            for x in range(x1, x2, 30):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}", "parse_error": null}]}
{"ts": "2026-07-17T15:21:04.409942+00:00", "type": "tool_call", "id": "chatcmpl-tool-9ab206cfd8c4ba5d", "name": "execute_blender_code", "arguments": {"code": "\nimport bpy\n\n# Render preview\nscene = bpy.context.scene\nscene.cycles.samples = 32\nscene.render.filepath = \"C:/tmp/still_life_preview9.png\"\nbpy.ops.render.render(write_still=True)\n\nimg = bpy.data.images.load(\"C:/tmp/still_life_preview9.png\")\nw, h = img.size[0], img.size[1]\npixels = list(img.pixels)\n\nprint(\"Brightness map (12x12 grid):\")\nfor gy in range(12):\n    row = \"\"\n    for gx in range(12):\n        x1 = gx * w // 12\n        x2 = (gx+1) * w // 12\n        y1 = gy * h // 12\n        y2 = (gy+1) * h // 12\n        bright_sum = 0\n        count = 0\n        for y in range(y1, y2, 30):\n            for x in range(x1, x2, 30):\n                idx = (y * w + x) * 4\n                if idx + 2 < len(pixels):\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\n                    count += 1\n        bright = bright_sum / count if count > 0 else 0\n        if bright < 0.06: row += \"  \"\n        elif bright < 0.12: row += \"· \"\n        elif bright < 0.2: row += \"• \"\n        elif bright < 0.3: row += \"○ \"\n        elif bright < 0.4: row += \"● \"\n        elif bright < 0.55: row += \"▓ \"\n        elif bright < 0.7: row += \"▒ \"\n        else: row += \"█ \"\n    print(f\"  Row {gy}: |{row}|\")\n\nresult = {\"status\": \"ok\"}\n"}, "raw_arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview9.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview9.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (12x12 grid):\\\")\\nfor gy in range(12):\\n    row = \\\"\\\"\\n    for gx in range(12):\\n        x1 = gx * w // 12\\n        x2 = (gx+1) * w // 12\\n        y1 = gy * h // 12\\n        y2 = (gy+1) * h // 12\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 30):\\n            for x in range(x1, x2, 30):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}
{"ts": "2026-07-17T15:21:35.810945+00:00", "type": "tool_result", "tool_call_id": "chatcmpl-tool-9ab206cfd8c4ba5d", "name": "execute_blender_code", "text": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (12x12 grid):\\n  Row 0: |· ·       · • • • • ·   |\\n  Row 1: |•     • ○ ○ • ·         |\\n  Row 2: |  • ● ○ • ·             |\\n  Row 3: |▓ ▓ ○                   |\\n  Row 4: |▒ ▒ ● •                 |\\n  Row 5: |▒ ▒ ▓ · ·               |\\n  Row 6: |▒ ▓ ● ○ •               |\\n  Row 7: |○ ● ▒ ▓ █ ▒ ● • ·       |\\n  Row 8: |  ▒ ▒ ▒ ▒ ▒ ▓ ▒ ▓ ● ○ · |\\n  Row 9: |▓ █ █ █ █ ▒ ▒ ▒ ▒ ▒ ▒ ▓ |\\n  Row 10: |█ █ █ █ █ █ ▒ ▒ ▒ ▒ ▒ ▒ |\\n  Row 11: |█ █ █ █ █ █ █ █ █ ▒ ▒ ▒ |\\n\"\n}", "is_error": false, "has_image": false, "image_b64": null}
{"ts": "2026-07-17T15:21:37.170465+00:00", "type": "llm_call", "call_index": 70, "provider_type": "blenderbench.providers.openrouter.OpenRouterProvider", "started_at": "2026-07-17T15:21:35.838391+00:00", "finished_at": "2026-07-17T15:21:37.160506+00:00", "duration_s": 1.312000000005355, "request": {"messages": [{"role": "system", "content": "You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\n\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\n\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\n\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\n\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\n\n## Harness Instructions\n\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\n\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls."}, {"role": "user", "content": "## Task\n\nComplete the following Blender task:\n\n<task>\n\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\n\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \"portrait\" gazing out of the arrangement.\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\n\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\n\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\n\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\n\n</task>"}, {"role": "assistant", "content": "Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\n\nLet me start by checking the current scene state and planning my approach.", "tool_calls": [{"id": "chatcmpl-tool-aadef2b898f113d4", "type": "function", "function": {"name": "get_blendfile_summary_datablocks", "arguments": "{}"}}, {"id": "chatcmpl-tool-945d697d0850e4b7", "type": "function", "function": {"name": "get_objects_summary", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-aadef2b898f113d4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"datablock_counts\": {\n      \"all_ids\": 35,\n      \"cameras\": 1,\n      \"collections\": 1,\n      \"images\": 2,\n      \"lights\": 1,\n      \"linestyles\": 1,\n      \"materials\": 2,\n      \"meshes\": 1,\n      \"palettes\": 1,\n      \"scenes\": 1,\n      \"screens\": 11,\n      \"window_managers\": 1,\n      \"workspaces\": 11,\n      \"worlds\": 1\n    },\n    \"render_engine\": \"BLENDER_EEVEE\",\n    \"scene_name\": \"Scene\",\n    \"workspaces\": [\n      \"Animation\",\n      \"Compositing\",\n      \"Geometry Nodes\",\n      \"Layout\",\n      \"Modeling\",\n      \"Rendering\",\n      \"Scripting\",\n      \"Sculpting\",\n      \"Shading\",\n      \"Texture Paint\",\n      \"UV Editing\"\n    ],\n    \"active_workspace\": \"Layout\"\n  }\n}"}, {"role": "tool", "tool_call_id": "chatcmpl-tool-945d697d0850e4b7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"scene_name\": \"Scene\",\n    \"active_workspace\": \"Layout\",\n    \"active_object\": null,\n    \"object_mode\": null,\n    \"camera_object\": null,\n    \"collections\": [\n      {\n        \"name\": \"Scene Collection\",\n        \"exclude\": false,\n        \"hide_viewport\": false,\n        \"objects\": [],\n        \"children\": [\n          {\n            \"name\": \"Collection\",\n            \"exclude\": false,\n            \"hide_viewport\": false,\n            \"objects\": [],\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"}, {"role": "assistant", "content": "The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\n\nLet me start with the scene foundation — render settings, color management, and clearing defaults.", "tool_calls": [{"id": "chatcmpl-tool-be3274dc62602abe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# --- Clear the scene ---\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete(use_global=False, confirm=False)\\nfor block in list(bpy.data.meshes):\\n    bpy.data.meshes.remove(block)\\nfor block in list(bpy.data.materials):\\n    bpy.data.materials.remove(block)\\nfor block in list(bpy.data.curves):\\n    bpy.data.curves.remove(block)\\nfor block in list(bpy.data.lights):\\n    bpy.data.lights.remove(block)\\nfor block in list(bpy.data.cameras):\\n    bpy.data.cameras.remove(block)\\nfor block in list(bpy.data.images):\\n    bpy.data.images.remove(block)\\n\\n# --- Render settings: Cycles ---\\nscene = bpy.context.scene\\nscene.render.engine = 'CYCLES'\\nscene.cycles.device = 'GPU'\\nscene.cycles.samples = 128\\nscene.cycles.use_denoising = True\\nscene.render.resolution_x = 1536\\nscene.render.resolution_y = 1536\\nscene.render.resolution_percentage = 100\\nscene.render.film_transparent = False\\n\\n# Color management - filmic for painterly look\\nscene.view_settings.view_transform = 'Filmic'\\nscene.view_settings.look = 'Medium High Contrast'\\nscene.view_settings.exposure = 0.0\\n\\n# World - very dark ambient (chiaroscuro)\\nworld = scene.world\\nif world is None:\\n    world = bpy.data.worlds.new(\\\"World\\\")\\n    scene.world = world\\nworld.use_nodes = True\\nwn = world.node_tree\\nfor n in list(wn.nodes):\\n    wn.nodes.remove(n)\\nbg = wn.nodes.new('ShaderNodeBackground')\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\nbg.inputs['Strength'].default_value = 0.3\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\n\\nprint(\\\"Scene foundation set up.\\\")\\nresult = {\\\"engine\\\": scene.render.engine, \\\"samples\\\": scene.cycles.samples, \\\"color_management\\\": scene.view_settings.view_transform}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-be3274dc62602abe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"engine\": \"CYCLES\",\n    \"samples\": 128,\n    \"color_management\": \"Filmic\"\n  },\n  \"stdout\": \"Scene foundation set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.", "tool_calls": [{"id": "chatcmpl-tool-894c8e93bee6e8c2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix, Euler\\n\\ndef link_obj(obj, collection_name=None):\\n    if collection_name:\\n        coll = bpy.data.collections.get(collection_name)\\n        if coll is None:\\n            coll = bpy.data.collections.new(collection_name)\\n            bpy.context.scene.collection.children.link(coll)\\n        coll.objects.link(obj)\\n    else:\\n        bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\n# ============================================================\\n\\n# --- Back wall (neutral dark grey) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\nback_wall = bpy.context.active_object\\nback_wall.name = \\\"BackWall\\\"\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\nback_wall.location = (0, 2.5, 2.0)\\nback_wall.scale = (6, 4, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Subdivide for subtle variation\\nbpy.context.view_layer.objects.active = back_wall\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=20)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Red wall panel (left side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\nred_panel = bpy.context.active_object\\nred_panel.name = \\\"RedPanel\\\"\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\nred_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Green wall panel (right side) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\ngreen_panel = bpy.context.active_object\\ngreen_panel.name = \\\"GreenPanel\\\"\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\ngreen_panel.scale = (2.5, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# --- Table top (aged wood) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\ntable = bpy.context.active_object\\ntable.name = \\\"TableTop\\\"\\ntable.scale = (6, 3.5, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Subdivide table for subtle surface variation\\nbpy.context.view_layer.objects.active = table\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=30)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\n# --- Table edge (front lip) ---\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\nedge = bpy.context.active_object\\nedge.name = \\\"TableEdge\\\"\\nedge.scale = (6, 0.1, 0.15)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# --- Floor (dark, extends to front) ---\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\nfloor = bpy.context.active_object\\nfloor.name = \\\"Floor\\\"\\nfloor.scale = (12, 8, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\nprint(\\\"Environment geometry built.\\\")\\nresult = {\\\"objects\\\": [o.name for o in bpy.data.objects]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-894c8e93bee6e8c2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"BackWall\",\n      \"Floor\",\n      \"GreenPanel\",\n      \"RedPanel\",\n      \"TableEdge\",\n      \"TableTop\"\n    ]\n  },\n  \"stdout\": \"Environment geometry built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.", "tool_calls": [{"id": "chatcmpl-tool-a446a83c48a104cb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector, Matrix\\n\\nrandom.seed(42)\\n\\n# ============================================================\\n# DRAPED CLOTHS with fold structure\\n# ============================================================\\n\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\n    \\\"\\\"\\\"Create a draped cloth plane with fold-like displacement.\\\"\\\"\\\"\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\n    obj = bpy.context.active_object\\n    obj.name = name\\n    obj.rotation_euler = rotation\\n    obj.scale = scale\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n    \\n    # Subdivide heavily for folds\\n    bpy.context.view_layer.objects.active = obj\\n    bpy.ops.object.mode_set(mode='EDIT')\\n    bpy.ops.mesh.select_all(action='SELECT')\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\n    bpy.ops.object.mode_set(mode='OBJECT')\\n    \\n    # Add folds via vertex displacement\\n    mesh = obj.data\\n    for v in mesh.vertices:\\n        x, y, z = v.co\\n        # Create fold-like ripples along the cloth\\n        fold_z = fold_intensity * (\\n            math.sin(x * fold_freq) * 0.5 +\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\n            math.cos(y * fold_freq * 0.7) * 0.2\\n        )\\n        # Dampen folds near attachment edge (top)\\n        edge_factor = min(1.0, abs(z) / 1.5)\\n        v.co.z += fold_z * edge_factor\\n    \\n    # Add solidify modifier for thickness\\n    mod = obj.modifiers.new(name=\\\"Solidify\\\", type='SOLIDIFY')\\n    mod.thickness = 0.015\\n    mod.offset = 0\\n    \\n    # Smooth shading\\n    bpy.ops.object.shade_smooth()\\n    \\n    return obj\\n\\n# --- Red velvet cloth (left side, draped from table edge) ---\\nred_cloth = create_draped_cloth(\\n    \\\"RedCloth\\\",\\n    location=(-2.2, -1.5, 0.02),\\n    rotation=(0, 0, 0),\\n    scale=(3.5, 3.0, 1),\\n    fold_intensity=0.12,\\n    fold_freq=6\\n)\\n\\n# --- Green velvet cloth (right side, on table surface) ---\\ngreen_cloth = create_draped_cloth(\\n    \\\"GreenCloth\\\",\\n    location=(2.0, 0.3, 0.02),\\n    rotation=(0, 0, math.radians(8)),\\n    scale=(3.0, 2.8, 1),\\n    fold_intensity=0.08,\\n    fold_freq=7\\n)\\n\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\nwhite_cloth = create_draped_cloth(\\n    \\\"WhiteCloth\\\",\\n    location=(0.0, -0.2, 0.03),\\n    rotation=(0, 0, 0),\\n    scale=(2.5, 2.2, 1),\\n    fold_intensity=0.04,\\n    fold_freq=10\\n)\\n\\nprint(\\\"Draped cloths built.\\\")\\nresult = {\\\"cloth_objects\\\": [\\\"RedCloth\\\", \\\"GreenCloth\\\", \\\"WhiteCloth\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a446a83c48a104cb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_objects\": [\n      \"RedCloth\",\n      \"GreenCloth\",\n      \"WhiteCloth\"\n    ]\n  },\n  \"stdout\": \"Draped cloths built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.", "tool_calls": [{"id": "chatcmpl-tool-8f91ff705ec7e347", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# THE UTAH TEAPOT — the hero\\n# Classic squat proportions, built from profile curves revolved\\n# ============================================================\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# --- Teapot Body: lathe a profile ---\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\nbody_profile = [\\n    (0.00, 0.00),   # center bottom\\n    (0.35, 0.00),   # base edge\\n    (0.55, 0.02),   # \\n    (0.70, 0.08),   # bulge start\\n    (0.82, 0.20),   # widest bulge lower\\n    (0.88, 0.35),   # widest point\\n    (0.87, 0.50),   # \\n    (0.80, 0.65),   # tapering up\\n    (0.70, 0.78),   # \\n    (0.55, 0.88),   # shoulder\\n    (0.40, 0.94),   # neck\\n    (0.32, 0.98),   # lid seat\\n    (0.30, 1.00),   # top opening edge\\n]\\n\\n# Build the body as a lathed mesh\\nmesh = bpy.data.meshes.new(\\\"TeapotBodyMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 48\\n# Create rings of vertices\\nall_verts = []\\nfor r, h in body_profile:\\n    ring = []\\n    if r < 0.001:\\n        # single vertex at center (pole)\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Create faces between rings\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = body_profile[ri]\\n    rb, _ = body_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            # triangle fan\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbody_obj = bpy.data.objects.new(\\\"TeapotBody\\\", mesh)\\nlink_obj(body_obj)\\nbpy.context.view_layer.objects.active = body_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add subdivision surface for smoothness\\nmod = body_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\nprint(\\\"Teapot body built.\\\")\\nresult = {\\\"verts\\\": len(mesh.vertices), \\\"faces\\\": len(mesh.polygons)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f91ff705ec7e347", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"verts\": 577,\n    \"faces\": 576\n  },\n  \"stdout\": \"Teapot body built.\\n\"\n}"}, {"role": "assistant", "content": "Now the teapot spout, handle, and lid.", "tool_calls": [{"id": "chatcmpl-tool-8655fd34dc5d3d15", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT SPOUT — curved tube\\n# ============================================================\\n# The spout rises from the lower body, curves outward and up\\n\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\nspout_curve_data.dimensions = '3D'\\nspout_curve_data.resolution_u = 16\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\n\\nspline = spout_curve_data.splines.new('BEZIER')\\n# Control points tracing the spout path (in body-local space)\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\nspout_points = [\\n    (0.82, 0, 0.22),   # base at body\\n    (1.05, 0, 0.30),   # curving out\\n    (1.25, 0, 0.45),   # mid\\n    (1.38, 0, 0.62),   # curving up\\n    (1.42, 0, 0.80),   # near tip\\n    (1.40, 0, 0.92),   # tip\\n]\\nspline.bezier_points.add(len(spout_points) - 1)\\nfor i, pt in enumerate(spout_points):\\n    bp = spline.bezier_points[i]\\n    bp.co = pt\\n    bp.handle_left_type = 'AUTO'\\n    bp.handle_right_type = 'AUTO'\\n\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\nlink_obj(spout_obj)\\n\\n# Convert curve to mesh, then taper it\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.select_all(action='DESELECT')\\nspout_obj.select_set(True)\\nbpy.ops.object.convert(target='MESH')\\n\\nspout_mesh = spout_obj.data\\n# Taper the spout: make it wider at base, narrower at tip\\n# The mesh from curve conversion has vertices along the path\\n# We'll scale based on z height\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\nz_range = max_z - min_z\\n\\nfor v in spout_mesh.vertices:\\n    # normalize position along path (0=base, 1=tip)\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\n    # Radius taper: thick at base, narrow at tip\\n    # Also widen the opening at the very tip (lip)\\n    if t > 0.85:\\n        # flare slightly at the spout lip\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\n    else:\\n        radius_factor = 0.18 - t * 0.06\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\n    # The spout extends along +x, so scale y and z-offset\\n    center_x = 1.1  # approximate path center\\n    v.co.y *= (radius_factor / 0.18)\\n    v.co.z = v.co.z  # keep z\\n\\n# Actually, let me rebuild the spout more carefully with a proper tube\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\n\\n# --- Rebuild spout as a proper tapered tube ---\\nmesh = bpy.data.meshes.new(\\\"TeapotSpoutMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Spout centerline points\\npath_points = [\\n    Vector((0.80, 0, 0.20)),\\n    Vector((1.00, 0, 0.26)),\\n    Vector((1.20, 0, 0.38)),\\n    Vector((1.34, 0, 0.55)),\\n    Vector((1.40, 0, 0.74)),\\n    Vector((1.38, 0, 0.90)),\\n]\\n# Radii at each point\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\n\\n# Generate rings\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    # Compute tangent (direction along path)\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    # Build a frame perpendicular to tangent\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\n# Connect rings with faces\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\n# Cap the tip (top) - the spout opening\\ntip_ring = rings[-1]\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\n# Don't cap - leave open as a spout opening, but add a slight rim\\n# Actually cap the base where it meets the body\\nbase_ring = rings[0]\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\n# Leave both open for now (base merges into body)\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nspout_obj = bpy.data.objects.new(\\\"TeapotSpout\\\", mesh)\\nlink_obj(spout_obj)\\nbpy.context.view_layer.objects.active = spout_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = spout_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Teapot spout built.\\\")\\nresult = {\\\"spout_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8655fd34dc5d3d15", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"spout_verts\": 144\n  },\n  \"stdout\": \"Teapot spout built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-bc4ec4ddd3e82626", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotHandleMesh\\\")\\nbm = bmesh.new()\\n\\nsegments = 24\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\n# Handle is on the -x side (opposite the spout)\\npath_points = [\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\n    Vector((-1.18, 0, 0.55)),   # outer\\n    Vector((-1.15, 0, 0.38)),   # mid\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\n]\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\n\\nrings = []\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\n    ring = []\\n    if pi == 0:\\n        tangent = (path_points[1] - path_points[0]).normalized()\\n    elif pi == len(path_points) - 1:\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\n    else:\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\n    \\n    up = Vector((0, 0, 1))\\n    if abs(tangent.dot(up)) > 0.9:\\n        up = Vector((1, 0, 0))\\n    right = tangent.cross(up).normalized()\\n    up = right.cross(tangent).normalized()\\n    \\n    for i in range(segments):\\n        angle = (i / segments) * math.tau\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\n        v = bm.verts.new(p + offset)\\n        ring.append(v)\\n    rings.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(rings) - 1):\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nhandle_obj = bpy.data.objects.new(\\\"TeapotHandle\\\", mesh)\\nlink_obj(handle_obj)\\nbpy.context.view_layer.objects.active = handle_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = handle_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# ============================================================\\n# TEAPOT LID — dome with knob\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"TeapotLidMesh\\\")\\nbm = bmesh.new()\\n\\n# Lid profile: sits on the neck, domes up, has a knob\\nlid_profile = [\\n    (0.00, 0.98),   # center\\n    (0.30, 0.98),   # seat edge (matches neck top)\\n    (0.30, 1.00),   # lip up\\n    (0.28, 1.02),   # \\n    (0.24, 1.06),   # dome\\n    (0.18, 1.10),   # \\n    (0.12, 1.13),   # \\n    (0.07, 1.15),   # knob base\\n    (0.05, 1.17),   # \\n    (0.04, 1.19),   # knob top\\n    (0.00, 1.19),   # knob cap\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in lid_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = lid_profile[ri]\\n    rb, _ = lid_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nlid_obj = bpy.data.objects.new(\\\"TeapotLid\\\", mesh)\\nlink_obj(lid_obj)\\nbpy.context.view_layer.objects.active = lid_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = lid_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 2\\nmod.render_levels = 3\\n\\n# Parent all teapot parts to an empty for easy positioning\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\nteapot_empty = bpy.context.active_object\\nteapot_empty.name = \\\"UtahTeapot\\\"\\nteapot_empty.empty_display_size = 0.5\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.parent = teapot_empty\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\n\\nprint(\\\"Teapot handle, lid built and parented.\\\")\\nresult = {\\\"teapot_parts\\\": [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bc4ec4ddd3e82626", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_parts\": [\n      \"TeapotBody\",\n      \"TeapotSpout\",\n      \"TeapotHandle\",\n      \"TeapotLid\"\n    ]\n  },\n  \"stdout\": \"Teapot handle, lid built and parented.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.", "tool_calls": [{"id": "chatcmpl-tool-9d958d1dbd0f2bc4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\n# Built from metaballs / shaped spheres for the rounded organic form\\n# ============================================================\\n\\n# Use a base mesh and shape it with proportional editing-like vertex math\\n# Start with a UV sphere and sculpt the bunny form\\n\\nmesh = bpy.data.meshes.new(\\\"BunnyMesh\\\")\\nbm = bmesh.new()\\n\\n# Create the bunny body as a series of merged spheres\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\n\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\nbody = bpy.context.active_object\\nbody.name = \\\"BunnyBodyTemp\\\"\\n\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\n# Body parts (in local space, will be positioned later):\\nparts = []\\n\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\n    \\\"\\\"\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\"\\\"\\\"\\n    verts_grid = []\\n    for ri in range(rings + 1):\\n        phi = math.pi * ri / rings  # 0 to pi\\n        ring = []\\n        for si in range(segments):\\n            theta = math.tau * si / segments\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\n            z = radius * math.cos(phi) * squash[2]\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\n            ring.append(v)\\n        verts_grid.append(ring)\\n    \\n    # Create faces\\n    for ri in range(rings):\\n        for si in range(segments):\\n            sj = (si + 1) % segments\\n            try:\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\n            except:\\n                pass\\n    return verts_grid\\n\\n# Delete temp object\\nbpy.data.objects.remove(body, do_unlink=True)\\n\\n# Build bunny as a union of squashed spheres\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\n\\n# Main body mass (large, elongated, crouched)\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\n# Lower body / haunches\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\n# Head (forward and slightly down)\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\n# Nose area\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\n\\n# Ears (folded back along the body) - two flattened elongated forms\\n# Left ear\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n# Right ear\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\n\\n# Front legs/paws (folded under)\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\n\\n# Back haunches (raised)\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nbunny_obj = bpy.data.objects.new(\\\"StanfordBunny\\\", mesh)\\nlink_obj(bunny_obj)\\nbpy.context.view_layer.objects.active = bunny_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\n# Use a remesh to blend the parts\\nremesh = bunny_obj.modifiers.new(\\\"Remesh\\\", 'REMESH')\\nremesh.mode = 'SMOOTH'\\nremesh.voxel_size = 0.03\\nremesh.adaptivity = 0.002\\n\\n# Add subsurf after remesh for extra smoothness\\nsubsurf = bunny_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nsubsurf.levels = 1\\nsubsurf.render_levels = 2\\n\\n# Scale to sit on table at reasonable size\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\n\\nprint(\\\"Stanford Bunny built.\\\")\\nresult = {\\\"bunny_verts\\\": len(mesh.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9d958d1dbd0f2bc4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"bunny_verts\": 10032\n  },\n  \"stdout\": \"Stanford Bunny built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.", "tool_calls": [{"id": "chatcmpl-tool-b30242086301c8e0", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\n# ============================================================\\n# SUZANNE — Blender's monkey head, as a bust\\n# ============================================================\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\nsuzanne = bpy.context.active_object\\nsuzanne.name = \\\"Suzanne\\\"\\n\\n# Add a simple bust base/pedestal under Suzanne\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\nbust_base = bpy.context.active_object\\nbust_base.name = \\\"SuzanneBase\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Taper the base slightly (classical bust pedestal)\\nbpy.context.view_layer.objects.active = bust_base\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=3)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n# Scale top vertices slightly\\nmesh = bust_base.data\\nfor v in mesh.vertices:\\n    if v.co.z > 0.04:\\n        v.co.x *= 0.7\\n        v.co.y *= 0.7\\n\\n# Parent base to Suzanne for now\\nbust_base.parent = suzanne\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\n\\nprint(\\\"Suzanne and bust base built.\\\")\\n\\n# ============================================================\\n# CHECKERED SPHERE — ray-tracing demo classic\\n# ============================================================\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\nsphere = bpy.context.active_object\\nsphere.name = \\\"CheckeredSphere\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Add subsurf for perfectly smooth sphere\\nmod = sphere.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\nprint(\\\"Checkered sphere built.\\\")\\nresult = {\\\"suzanne_verts\\\": len(suzanne.data.vertices), \\\"sphere_verts\\\": len(sphere.data.vertices)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b30242086301c8e0", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_verts\": 507,\n    \"sphere_verts\": 1986\n  },\n  \"stdout\": \"Suzanne and bust base built.\\nCheckered sphere built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.", "tool_calls": [{"id": "chatcmpl-tool-b3944ff151600684", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector, Matrix\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# WINE GLASS — classical still life prop\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"WineGlassMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the wine glass (radius, height) — lathed\\nglass_profile = [\\n    (0.00, 0.00),    # base center\\n    (0.14, 0.00),    # base edge\\n    (0.15, 0.01),    # base lip\\n    (0.13, 0.02),    # \\n    (0.04, 0.03),    # stem base\\n    (0.035, 0.10),   # stem\\n    (0.035, 0.18),   # stem\\n    (0.04, 0.25),    # bowl base\\n    (0.08, 0.30),    # bowl widening\\n    (0.12, 0.36),    # \\n    (0.14, 0.42),    # bowl widest\\n    (0.135, 0.48),   # \\n    (0.11, 0.53),    # tapering in\\n    (0.08, 0.57),    # \\n    (0.06, 0.60),    # rim\\n    (0.00, 0.60),    # center top (open)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in glass_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = glass_profile[ri]\\n    rb, _ = glass_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Don't cap the top - leave open\\n            pass\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nglass_obj = bpy.data.objects.new(\\\"WineGlass\\\", mesh)\\nlink_obj(glass_obj)\\nbpy.context.view_layer.objects.active = glass_obj\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify for glass thickness\\nmod = glass_obj.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.004\\nmod.offset = 1\\n\\n# ============================================================\\n# OPEN BOOK — classical still life prop\\n# ============================================================\\n# Book base (two pages meeting at spine)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\nbook = bpy.context.active_object\\nbook.name = \\\"OpenBook\\\"\\nbook.scale = (0.45, 0.32, 0.03)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape the pages - create a V-shape for open book\\nbpy.context.view_layer.objects.active = book\\nbpy.ops.object.mode_set(mode='EDIT')\\nbpy.ops.mesh.select_all(action='SELECT')\\nbpy.ops.mesh.subdivide(number_cuts=8)\\nbpy.ops.object.mode_set(mode='OBJECT')\\n\\nmesh = book.data\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\nfor v in mesh.vertices:\\n    # Distance from center line (x=0 is spine)\\n    dist_from_spine = abs(v.co.x)\\n    # Pages curve up at edges\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\n    # Spine dips\\n    if dist_from_spine < 0.05:\\n        v.co.z -= 0.01\\n\\n# Add a second thin cube for the cover (darker)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\ncover = bpy.context.active_object\\ncover.name = \\\"BookCover\\\"\\ncover.scale = (0.48, 0.34, 0.015)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Shape cover to match\\nmesh = cover.data\\nfor v in mesh.vertices:\\n    dist_from_spine = abs(v.co.x)\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\n\\n# ============================================================\\n# FRUIT — a few oranges/lemons for color and life\\n# ============================================================\\nfruits = []\\nfruit_colors = [\\n    ((0.10, 0, 0), 0.09, \\\"Orange1\\\"),   # orange, slight offset\\n    ((0.18, 0.08, 0), 0.075, \\\"Orange2\\\"),  # orange, different position\\n    ((0.0, 0.12, 0), 0.08, \\\"Lemon1\\\"),   # lemon\\n]\\n\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\n    fruit = bpy.context.active_object\\n    fruit.name = name\\n    # Squash slightly for fruit shape\\n    fruit.scale = (1.0, 1.0, 0.88)\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n    bpy.ops.object.shade_smooth()\\n    fruits.append(fruit)\\n\\nprint(\\\"Wine glass, book, and fruit built.\\\")\\nresult = {\\\"objects\\\": [\\\"WineGlass\\\", \\\"OpenBook\\\", \\\"BookCover\\\"] + [f.name for f in fruits]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b3944ff151600684", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"objects\": [\n      \"WineGlass\",\n      \"OpenBook\",\n      \"BookCover\",\n      \"Orange1\",\n      \"Orange2\",\n      \"Lemon1\"\n    ]\n  },\n  \"stdout\": \"Wine glass, book, and fruit built.\\n\"\n}"}, {"role": "assistant", "content": "Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.", "tool_calls": [{"id": "chatcmpl-tool-a11b11ab0c461694", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# COMPOSITION: Position all objects on the table\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\n# Teapot commands the arrangement (center-hero), others grouped around\\n# ============================================================\\n\\n# Table surface is at z=0\\n# Camera will look from front-left, slightly elevated\\n\\n# --- Utah Teapot (hero, center, commanding) ---\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (-0.1, 0.1, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\nteapot.scale = (0.85, 0.85, 0.85)\\n\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.15, 0.25, 0.03)\\nbunny.rotation_euler = (0, 0, math.radians(40))\\nbunny.scale = (1.3, 1.3, 1.3)\\n\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.05, 0.18)\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\n\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.15, -0.55, 0.22)\\n\\n# --- Wine Glass (right side, back) ---\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.55, 0.3, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\n# --- Open Book (left-front, partially under bunny) ---\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.6, -0.7, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(15))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location\\ncover.rotation_euler = book.rotation_euler\\n\\n# --- Fruit (clustered near front-right) ---\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.85, -0.75, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.05, -0.65, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, 0)\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.7, -0.55, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\n\\nprint(\\\"All objects positioned.\\\")\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a11b11ab0c461694", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"BackWall\": [\n      0.0,\n      2.5,\n      2.0\n    ],\n    \"BookCover\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"CheckeredSphere\": [\n      0.15000000596046448,\n      -0.550000011920929,\n      0.2199999988079071\n    ],\n    \"Floor\": [\n      0.0,\n      -3.0,\n      -0.20000000298023224\n    ],\n    \"GreenCloth\": [\n      2.0,\n      0.30000001192092896,\n      0.019999999552965164\n    ],\n    \"GreenPanel\": [\n      2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"Lemon1\": [\n      0.699999988079071,\n      -0.550000011920929,\n      0.07999999821186066\n    ],\n    \"OpenBook\": [\n      -0.6000000238418579,\n      -0.699999988079071,\n      0.019999999552965164\n    ],\n    \"Orange1\": [\n      0.8500000238418579,\n      -0.75,\n      0.09000000357627869\n    ],\n    \"Orange2\": [\n      1.0499999523162842,\n      -0.6499999761581421,\n      0.07500000298023224\n    ],\n    \"RedCloth\": [\n      -2.200000047683716,\n      -1.5,\n      0.019999999552965164\n    ],\n    \"RedPanel\": [\n      -2.799999952316284,\n      1.7999999523162842,\n      2.200000047683716\n    ],\n    \"StanfordBunny\": [\n      -1.149999976158142,\n      0.25,\n      0.029999999329447746\n    ],\n    \"Suzanne\": [\n      1.0,\n      -0.05000000074505806,\n      0.18000000715255737\n    ],\n    \"SuzanneBase\": [\n      0.0,\n      0.0,\n      -0.15000000596046448\n    ],\n    \"TableEdge\": [\n      0.0,\n      -1.75,\n      -0.05000000074505806\n    ],\n    \"TableTop\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotBody\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotHandle\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotLid\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"TeapotSpout\": [\n      0.0,\n      0.0,\n      0.0\n    ],\n    \"UtahTeapot\": [\n      -0.10000000149011612,\n      0.10000000149011612,\n      0.0\n    ],\n    \"WhiteCloth\": [\n      0.0,\n      -0.20000000298023224,\n      0.029999999329447746\n    ],\n    \"WineGlass\": [\n      1.5499999523162842,\n      0.30000001192092896,\n      0.0\n    ]\n  },\n  \"stdout\": \"All objects positioned.\\n\"\n}"}, {"role": "assistant", "content": "Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.", "tool_calls": [{"id": "chatcmpl-tool-971ae09b09cd7c7d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# MATERIALS\\n# ============================================================\\n\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\nmat, nt = create_material(\\\"M_TeapotCeramic\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n# Add subtle noise for ceramic imperfection\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\nnoise.inputs['Scale'].default_value = 35.0\\nnoise.inputs['Detail'].default_value = 8.0\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.15\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n# Color variation\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise2.inputs['Scale'].default_value = 8.0\\nnoise2.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    if obj.data.materials:\\n        obj.data.materials[0] = mat\\n    else:\\n        obj.data.materials.append(mat)\\n\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\nmat, nt = create_material(\\\"M_BunnyBronze\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation (greenish patches)\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\nnoise.inputs['Scale'].default_value = 4.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Roughness variation\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 50.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nif bunny.data.materials:\\n    bunny.data.materials[0] = mat\\nelse:\\n    bunny.data.materials.append(mat)\\n\\nprint(\\\"Teapot and bunny materials created.\\\")\\nresult = {\\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\", \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-971ae09b09cd7c7d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"teapot_mat\": \"M_TeapotCeramic\",\n    \"bunny_mat\": \"M_BunnyBronze\"\n  },\n  \"stdout\": \"Teapot and bunny materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a5082ce8c009bea7", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 3. SUZANNE: Marble bust material ---\\nmat, nt = create_material(\\\"M_SuzanneMarble\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.3\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnoise.inputs['Distortion'].default_value = 1.5\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\nwave.inputs['Scale'].default_value = 2.0\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = historyMat\\nelse:\\n    suzanne.data.materials.append(mat)\\n\\n# Bust base - darker marble\\nmat_base, nt = create_material(\\\"M_BustBase\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.4\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nif base.data.materials:\\n    base.data.materials[0] = mat_base\\nelse:\\n    base.data.materials.append(mat_base)\\n\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\nmat, nt = create_material(\\\"M_CheckeredSphere\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\n\\n# Checker pattern\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 12.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nif sphere.data.materials:\\n    sphere.data.materials[0] = mat\\nelse:\\n    sphere.data.materials.append(mat)\\n\\nprint(\\\"Suzanne, bust base, and checkered sphere materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a5082ce8c009bea7", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne, bust base, and checkered sphere materials created.\\n\"\n}"}, {"role": "assistant", "content": "I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.", "tool_calls": [{"id": "chatcmpl-tool-b99d874b987317e9", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix Suzanne material assignment\\nmat_suzanne = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nif suzanne.data.materials:\\n    suzanne.data.materials[0] = mat_suzanne\\nelse:\\n    suzanne.data.materials.append(mat_suzanne)\\n\\nprint(\\\"Fixed Suzanne material.\\\")\\nresult = {\\\"suzanne_materials\\\": [m.name for m in suzanne.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b99d874b987317e9", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"suzanne_materials\": [\n      \"M_SuzanneMarble\"\n    ]\n  },\n  \"stdout\": \"Fixed Suzanne material.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a837f3bf886e2bf3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\n# Velvet sheen via noise\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Cloth bump for weave\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a837f3bf886e2bf3", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 58, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Rec\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": "Let me fix that typo — I used `Rec` instead of `Fac`.", "tool_calls": [{"id": "chatcmpl-tool-85fb82aff4f7bc91", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\nmat, nt = create_material(\\\"M_RedVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"RedCloth\\\"].data.materials.append(mat)\\n\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\nmat, nt = create_material(\\\"M_GreenVelvet\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.85\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 15.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 120.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"GreenCloth\\\"].data.materials.append(mat)\\n\\n# --- 7. WHITE/GREY LINEN ---\\nmat, nt = create_material(\\\"M_WhiteLinen\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 20.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 150.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"WhiteCloth\\\"].data.materials.append(mat)\\n\\nprint(\\\"Cloth materials created.\\\")\\nresult = {\\\"cloth_materials\\\": [\\\"M_RedVelvet\\\", \\\"M_GreenVelvet\\\", \\\"M_WhiteLinen\\\"]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-85fb82aff4f7bc91", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"cloth_materials\": [\n      \"M_RedVelvet\",\n      \"M_GreenVelvet\",\n      \"M_WhiteLinen\"\n    ]\n  },\n  \"stdout\": \"Cloth materials created.\\n\"\n}"}, {"role": "assistant", "content": "Now the environment and remaining prop materials — walls, table, fruit, glass, book.", "tool_calls": [{"id": "chatcmpl-tool-b552d51ab059a6e8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL (dark, aged plaster) ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP (aged wood) ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\n# Wood grain\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\n\\n# Table edge and floor share table material\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b552d51ab059a6e8", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 59\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\n                 ^^^^^^^^^^^^^^^^^\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad7c6aebd182a662", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 8. BACK WALL ---\\nmat, nt = create_material(\\\"M_BackWall\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 8.0\\nnoise.inputs['Detail'].default_value = 6.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.3\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 30.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"BackWall\\\"].data.materials.append(mat)\\n\\n# --- 9. RED PANEL ---\\nmat, nt = create_material(\\\"M_RedPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"RedPanel\\\"].data.materials.append(mat)\\n\\n# --- 10. GREEN PANEL ---\\nmat, nt = create_material(\\\"M_GreenPanel\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"GreenPanel\\\"].data.materials.append(mat)\\n\\n# --- 11. TABLE TOP ---\\nmat, nt = create_material(\\\"M_TableTop\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.6\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\nwave.wave_type = 'BANDS'\\nwave.inputs['Scale'].default_value = 2.0\\nwave.inputs['Distortion'].default_value = 8.0\\nwave.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"TableTop\\\"].data.materials.append(mat)\\nbpy.data.objects[\\\"TableEdge\\\"].data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 12. FLOOR ---\\nmat, nt = create_material(\\\"M_Floor\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.9\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Floor\\\"].data.materials.append(mat)\\n\\nprint(\\\"Environment materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7c6aebd182a662", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Environment materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a15057346df8e108", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- 13. WINE GLASS (glass with wine) ---\\nmat, nt = create_material(\\\"M_WineGlass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\nglass.inputs['Roughness'].default_value = 0.0\\nglass.inputs['IOR'].default_value = 1.45\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"WineGlass\\\"].data.materials.append(mat)\\n\\n# --- 14. BOOK PAGES (aged paper) ---\\nmat, nt = create_material(\\\"M_BookPages\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\nbsdf.inputs['Roughness'].default_value = 0.85\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"OpenBook\\\"].data.materials.append(mat)\\n\\n# --- 15. BOOK COVER (aged leather - dark) ---\\nmat, nt = create_material(\\\"M_BookCover\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\nbsdf.inputs['Roughness'].default_value = 0.65\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"BookCover\\\"].data.materials.append(mat)\\n\\n# --- 16. ORANGES ---\\nmat, nt = create_material(\\\"M_Orange\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\n# Orange peel texture\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.5\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 60.0\\nnoise.inputs['Detail'].default_value = 2.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nfor name in [\\\"Orange1\\\", \\\"Orange2\\\"]:\\n    bpy.data.objects[name].data.materials.append(mat)\\n\\n# --- 17. LEMON ---\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Prop materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"materials\\\": [m.name for m in bpy.data.materials]}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a15057346df8e108", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 77, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"B\\\" not found'\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-b29a2fe5c411d5a8", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\nmat = bpy.data.materials.get(\\\"M_Lemon\\\")\\nif mat:\\n    bpy.data.materials.remove(mat)\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# Re-create lemon with correct output\\nmat, nt = create_material(\\\"M_Lemon\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.7\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.4\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise.inputs['Scale'].default_value = 80.0\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Lemon1\\\"].data.materials.append(mat)\\n\\nprint(\\\"Lemon material fixed.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b29a2fe5c411d5a8", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Lemon material fixed.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.", "tool_calls": [{"id": "chatcmpl-tool-b0d781dd9dc96405", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\n# ============================================================\\n\\n# --- Key light: warm window shaft from the left ---\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 800\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\nkey_light.data.size = 2.0\\nkey_light.data.size_y = 3.5\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\n\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Cool\\\"\\nfill_light.data.energy = 30\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\nfill_light.data.size = 3.0\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\n\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight\\\"\\nrim_light.data.energy = 100\\nrim_light.data.color = (1.0, 0.8, 0.5)\\nrim_light.data.spot_size = math.radians(60)\\nrim_light.data.spot_blend = 0.8\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\n\\n# --- Window frame light (creates the shaft pattern) ---\\n# A narrow area light to simulate light coming through a window\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\nwindow_light = bpy.context.active_object\\nwindow_light.name = \\\"WindowLight\\\"\\nwindow_light.data.energy = 400\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\nwindow_light.data.size = 0.8\\nwindow_light.data.size_y = 1.5\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\n\\nprint(\\\"Lighting set up.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b0d781dd9dc96405", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Cool\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight\",\n      \"WindowLight\"\n    ]\n  },\n  \"stdout\": \"Lighting set up.\\n\"\n}"}, {"role": "assistant", "content": "Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.", "tool_calls": [{"id": "chatcmpl-tool-81d514f5f212c1fe", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\n# ============================================================\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\ncam = bpy.context.active_object\\ncam.name = \\\"Camera_Presentation\\\"\\ncam.data.lens = 50  # 50mm focal length\\ncam.data.sensor_width = 36  # full frame\\ncam.data.sensor_height = 36  # square format for 1536x1536\\n\\n# Point camera at the teapot (center of arrangement)\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\ndirection = target - cam.location\\n# Convert direction to rotation\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\n\\n# Set as active scene camera\\nbpy.context.scene.camera = cam\\n\\n# Depth of field - subtle, focused on teapot\\ncam.data.dof.use_dof = True\\ncam.data.dof.focus_distance = (cam.location - target).length\\ncam.data.dof.aperture_fstop = 4.0\\n\\nprint(\\\"Camera set up.\\\")\\nresult = {\\n    \\\"camera_location\\\": list(cam.location),\\n    \\\"camera_rotation\\\": [math.degrees(r) for r in cam.rotation_euler],\\n    \\\"lens\\\": cam.data.lens,\\n    \\\"focus_distance\\\": cam.data.dof.focus_distance\\n}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81d514f5f212c1fe", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"camera_location\": [\n      3.200000047683716,\n      -3.799999952316284,\n      2.200000047683716\n    ],\n    \"camera_rotation\": [\n      70.59100910988977,\n      -1.0795828508605228e-6,\n      40.236364362789146\n    ],\n    \"lens\": 50.0,\n    \"focus_distance\": 5.416640758514404\n  },\n  \"stdout\": \"Camera set up.\\n\"\n}"}, {"role": "assistant", "content": "Let me do a quick render preview to see where we are, then I'll refine.", "tool_calls": [{"id": "chatcmpl-tool-80a032b133fec618", "type": "function", "function": {"name": "render_thumbnail_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_preview1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-80a032b133fec618", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_preview1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91107c27573cb421", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91107c27573cb421", "content": ""}, {"role": "assistant", "content": "Let me look at the rendered image to evaluate.", "tool_calls": [{"id": "chatcmpl-tool-97c7b5546a1ad792", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Check what the render output looks like by examining the image\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\nprint(f\\\"Image size: {img.size[0]}x{img.size[1]}\\\")\\nprint(f\\\"Image channels: {img.channels}\\\")\\n# Get some pixel values to check if it's rendering properly\\npixels = list(img.pixels[:20])\\nprint(f\\\"First pixels: {pixels}\\\")\\nresult = {\\\"image_size\\\": list(img.size), \\\"loaded\\\": True}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-97c7b5546a1ad792", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"image_size\": [\n      1536,\n      1536\n    ],\n    \"loaded\": true\n  },\n  \"stdout\": \"Image size: 1536x1536\\nImage channels: 4\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a7524c48acac6867", "type": "function", "function": {"name": "get_screenshot_of_window_as_json", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a7524c48acac6867", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"window_width\": 1920,\n    \"window_height\": 1111,\n    \"screen_name\": \"Layout\",\n    \"workspace\": \"Layout\",\n    \"scene\": \"Scene\",\n    \"areas\": [\n      {\n        \"type\": \"PROPERTIES\",\n        \"x\": 1579,\n        \"y\": 29,\n        \"width\": 339,\n        \"height\": 854,\n        \"space\": {\n          \"type\": \"PROPERTIES\",\n          \"context\": \"OBJECT\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 851,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"NAVIGATION_BAR\",\n            \"x\": 1579,\n            \"y\": 29,\n            \"width\": 36,\n            \"height\": 822\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1615,\n            \"y\": 29,\n            \"width\": 303,\n            \"height\": 822\n          }\n        ]\n      },\n      {\n        \"type\": \"OUTLINER\",\n        \"x\": 1579,\n        \"y\": 886,\n        \"width\": 339,\n        \"height\": 192,\n        \"space\": {\n          \"type\": \"OUTLINER\",\n          \"display_mode\": \"VIEW_LAYER\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 1579,\n            \"y\": 1046,\n            \"width\": 339,\n            \"height\": 32\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 1579,\n            \"y\": 886,\n            \"width\": 339,\n            \"height\": 160\n          }\n        ]\n      },\n      {\n        \"type\": \"DOPESHEET_EDITOR\",\n        \"x\": 2,\n        \"y\": 29,\n        \"width\": 1574,\n        \"height\": 75,\n        \"space\": {\n          \"type\": \"DOPESHEET_EDITOR\"\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 72,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"FOOTER\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"CHANNELS\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 29,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 29,\n            \"width\": 1574,\n            \"height\": 43\n          }\n        ]\n      },\n      {\n        \"type\": \"VIEW_3D\",\n        \"x\": 2,\n        \"y\": 107,\n        \"width\": 1574,\n        \"height\": 971,\n        \"space\": {\n          \"type\": \"VIEW_3D\",\n          \"view_perspective\": \"PERSP\",\n          \"view_location\": [\n            -0.020693248137831688,\n            -0.04602546989917755,\n            0.0006694307667203248\n          ],\n          \"shading_type\": \"SOLID\",\n          \"show_overlays\": true\n        },\n        \"regions\": [\n          {\n            \"type\": \"HEADER\",\n            \"x\": 2,\n            \"y\": 1046,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"TOOL_HEADER\",\n            \"x\": 2,\n            \"y\": 1014,\n            \"width\": 1574,\n            \"height\": 32\n          },\n          {\n            \"type\": \"ASSET_SHELF\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"ASSET_SHELF_HEADER\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"TOOLS\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 70,\n            \"height\": 907\n          },\n          {\n            \"type\": \"UI\",\n            \"x\": 1575,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"HUD\",\n            \"x\": 72,\n            \"y\": 107,\n            \"width\": 1,\n            \"height\": 1\n          },\n          {\n            \"type\": \"WINDOW\",\n            \"x\": 2,\n            \"y\": 107,\n            \"width\": 1574,\n            \"height\": 971\n          }\n        ]\n      }\n    ],\n    \"active_object\": {\n      \"name\": \"Camera_Presentation\",\n      \"type\": \"CAMERA\",\n      \"mode\": \"OBJECT\",\n      \"location\": [\n        3.200000047683716,\n        -3.799999952316284,\n        2.200000047683716\n      ]\n    },\n    \"selected_objects\": [\n      {\n        \"name\": \"Camera_Presentation\",\n        \"type\": \"CAMERA\"\n      }\n    ],\n    \"message\": null\n  }\n}"}, {"role": "assistant", "content": "Let me switch to the rendered view to see the output.", "tool_calls": [{"id": "chatcmpl-tool-8e4c646f6f5eaca4", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n# Set viewport to rendered mode to see the result\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'VIEW_3D':\\n        for space in area.spaces:\\n            if space.type == 'VIEW_3D':\\n                space.shading.type = 'RENDERED'\\n                break\\n        break\\nprint(\\\"Set viewport to rendered\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8e4c646f6f5eaca4", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Set viewport to rendered\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-879a01af15b1da65", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-879a01af15b1da65", "content": ""}, {"role": "assistant", "content": "Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.", "tool_calls": [{"id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.get(\\\"still_life_preview1.png\\\")\\nif img is None:\\n    # Load the rendered image\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Sample various regions of the image\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            r_sum += pixels[idx]\\n            g_sum += pixels[idx+1]\\n            b_sum += pixels[idx+2]\\n            count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\")\\n    return r_avg, g_avg, b_avg\\n\\n# Sample center, corners, and regions\\nsample_region(0, 0, w//4, h//4, \\\"Top-left (bg)\\\")\\nsample_region(3*w//4, 3*h//4, w, h, \\\"Bottom-right (fg)\\\")\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\"Center (objects)\\\")\\nsample_region(0, 3*h//4, w//4, h, \\\"Bottom-left\\\")\\nsample_region(3*w//4, 0, w, h//4, \\\"Top-right\\\")\\n\\n# Check overall brightness\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\nprint(f\\\"\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac3fa7e5b9d09b8b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Top-left (bg): R=0.280 G=0.219 B=0.149\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\nCenter (objects): R=0.518 G=0.470 B=0.384\\nBottom-left: R=0.084 G=0.061 B=0.050\\nTop-right: R=0.217 G=0.411 B=0.143\\n\\nOverall brightness sample: 0.407\\n\"\n}"}, {"role": "assistant", "content": "The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.", "tool_calls": [{"id": "chatcmpl-tool-921480628bdd2acf", "type": "function", "function": {"name": "render_viewport_to_path", "arguments": "{\"output_path\": \"C:/tmp/still_life_render1.png\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-921480628bdd2acf", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"filepath\": \"C:\\\\Users\\\\proud\\\\AppData\\\\Local\\\\Temp\\\\blender_a87204\\\\blender_mcp\\\\still_life_render1.png\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-af37df6737703d4f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimg = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check more regions to understand composition\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\n    for y in range(y_start, y_end, 10):\\n        for x in range(x_start, x_end, 10):\\n            idx = (y * w + x) * 4\\n            if idx + 2 < len(pixels):\\n                r_sum += pixels[idx]\\n                g_sum += pixels[idx+1]\\n                b_sum += pixels[idx+2]\\n                count += 1\\n    r_avg = r_sum / count if count > 0 else 0\\n    g_avg = g_sum / count if count > 0 else 0\\n    b_avg = b_sum / count if count > 0 else 0\\n    print(f\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\")\\n\\n# Grid sampling\\nfor gy in range(4):\\n    for gx in range(4):\\n        x1 = gx * w // 4\\n        x2 = (gx+1) * w // 4\\n        y1 = gy * h // 4\\n        y2 = (gy+1) * h // 4\\n        sample_region(x1, y1, x2, y2, f\\\"Grid[{gx},{gy}]\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-af37df6737703d4f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9e8d1c3844120289", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\n# Let me analyze the composition more carefully\\n# The grid shows: left side has warm light, right side has green, center has objects\\n# Bottom-left is very dark (good for chiaroscuro)\\n# Let me check if objects are visible and well-placed\\n\\nimport bpy\\nimg = bpy.data.images.get(\\\"still_life_render1.png\\\")\\nif img is None:\\n    img = bpy.data.images.load(\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\")\\n\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Check for the teapot area (should be center-ish, bright ceramic)\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\n\\n# Let me check if we can see bright highlights (ceramic teapot)\\nbright_count = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\n        bright_count += 1\\n\\nprint(f\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\")\\n\\n# Check if the sphere is visible (should be dark/light checker pattern)\\n# Check middle-bottom area\\nmid_bot_bright = 0\\nfor y in range(int(h*0.4), int(h*0.6)):\\n    for x in range(int(w*0.4), int(w*0.6)):\\n        idx = (y * w + x) * 4\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\nprint(f\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\", \\\"bright_pixels_pct\\\": 100*bright_count/(len(pixels)//4)}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9e8d1c3844120289", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\",\n    \"bright_pixels_pct\": 11.747021145290798\n  },\n  \"stdout\": \"Bright highlight pixels: 277147 / 2359296 (11.7%)\\nCenter brightness avg: 0.518\\n\"\n}"}, {"role": "assistant", "content": "The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.", "tool_calls": [{"id": "chatcmpl-tool-8a435cbbf4d6dda0", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8a435cbbf4d6dda0", "content": ""}, {"role": "assistant", "content": "Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.", "tool_calls": [{"id": "chatcmpl-tool-a0fd0dc86e72eae1", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check all objects and their modifiers\\nfor obj in bpy.data.objects:\\n    if obj.type == 'MESH':\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\n        print(f\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a0fd0dc86e72eae1", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "I see some material duplication issues. Let me clean those up and make refinements to improve the scene.", "tool_calls": [{"id": "chatcmpl-tool-975cf092ec3d5919", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Fix material assignments - clean up duplicates\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\nred_cloth.data.materials.clear()\\nred_cloth.data.materials.append(bpy.data.materials[\\\"M_RedVelvet\\\"])\\n\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\ngreen_cloth.data.materials.clear()\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\"M_GreenVelvet\\\"])\\n\\n# Remove duplicate materials\\nfor mat_name in [\\\"M_RedVelvet.001\\\", \\\"M_GreenVelvet.001\\\"]:\\n    mat = bpy.data.materials.get(mat_name)\\n    if mat:\\n        bpy.data.materials.remove(mat)\\n\\n# Verify\\nfor name in [\\\"RedCloth\\\", \\\"GreenCloth\\\"]:\\n    obj = bpy.data.objects[name]\\n    print(f\\\"{name}: {[m.name for m in obj.data.materials]}\\\")\\n\\nprint(f\\\"\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-975cf092ec3d5919", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"RedCloth: ['M_RedVelvet']\\nGreenCloth: ['M_GreenVelvet']\\n\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\n\"\n}"}, {"role": "assistant", "content": "Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.", "tool_calls": [{"id": "chatcmpl-tool-a250101a80c6b1b3", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# Fix Suzanne base positioning\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\n# The base should be under her, on the table\\n\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\n\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\n# Place base right under her\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\nbase.scale = (1.0, 1.0, 1.0)\\n\\n# Make sure Suzanne is resting on the base\\nsuzanne.location.z = 0.18\\n\\n# Apply Suzanne's rotation to the base too\\nbase.rotation_euler = (0, 0, 0)\\n\\nprint(f\\\"Suzanne: {list(suzanne.location)}\\\")\\nprint(f\\\"Base: {list(base.location)}\\\")\\n\\n# Now let me also check the bunny - make sure it sits on the table\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\n# The bunny's lowest point should be at z=0 (table surface)\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\n# Let's check its bounding box\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\n# Lowest parts are the paws at z=0, so it should sit on table\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\n\\n# Adjust bunny rotation so it faces slightly toward camera\\nbunny.rotation_euler = (0, 0, math.radians(40))\\n\\nprint(f\\\"Bunny: {list(bunny.location)}\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a250101a80c6b1b3", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\n\"\n}"}, {"role": "assistant", "content": "Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.", "tool_calls": [{"id": "chatcmpl-tool-b61f025e64068731", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Temporarily reduce samples for faster preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\n\\n# Set render output\\nscene.render.filepath = \\\"C:/tmp/still_life_preview2.png\\\"\\n\\n# Render\\nbpy.ops.render.render(write_still=True)\\n\\nprint(\\\"Preview render complete.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b61f025e64068731", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Preview render complete.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-838028367162311c", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed grid analysis\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (4x6 grid):\\\")\\nfor gy in range(6):\\n    row = \\\"\\\"\\n    for gx in range(6):\\n        x1 = gx * w // 6\\n        x2 = (gx+1) * w // 6\\n        y1 = gy * h // 6\\n        y2 = (gy+1) * h // 6\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 15):\\n            for x in range(x1, x2, 15):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        # Create ASCII brightness map\\n        if bright < 0.1: row += \\\"  \\\"\\n        elif bright < 0.2: row += \\\"· \\\"\\n        elif bright < 0.3: row += \\\"• \\\"\\n        elif bright < 0.4: row += \\\"○ \\\"\\n        elif bright < 0.5: row += \\\"☀ \\\"\\n        elif bright < 0.6: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-838028367162311c", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (4x6 grid):\\n  Row 0: |• · • •     |\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\n  Row 2: |▒ █ ☀ ○ ○ · |\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": "I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.", "tool_calls": [{"id": "chatcmpl-tool-8890c007fcce85eb", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Set the render output to show in the image editor\\nfor area in bpy.context.screen.areas:\\n    if area.type == 'IMAGE_EDITOR':\\n        for space in area.spaces:\\n            if space.type == 'IMAGE_EDITOR':\\n                img = bpy.data.images.load(\\\"C:/tmp/still_life_preview2.png\\\")\\n                space.image = img\\n                break\\n        break\\n\\n# Also try to view it in the 3D viewport as background\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8890c007fcce85eb", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  }\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a31aecfdef27c07a", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a31aecfdef27c07a", "content": ""}, {"role": "assistant", "content": "Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.", "tool_calls": [{"id": "chatcmpl-tool-a6b2fe3e89402cda", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REFINEMENTS: Better lighting, composition, and materials\\n# ============================================================\\n\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\n# Remove existing lights\\nfor obj in list(bpy.data.objects):\\n    if obj.type == 'LIGHT':\\n        bpy.data.objects.remove(obj, do_unlink=True)\\n\\n# Key light: warm window shaft from upper-left, more dramatic\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\nkey_light = bpy.context.active_object\\nkey_light.name = \\\"KeyLight_WarmShaft\\\"\\nkey_light.data.energy = 1200\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\nkey_light.data.size = 1.5\\nkey_light.data.size_y = 2.5\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\n\\n# Very subtle fill from right to prevent total blackness\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\nfill_light = bpy.context.active_object\\nfill_light.name = \\\"FillLight_Dim\\\"\\nfill_light.data.energy = 15\\nfill_light.data.color = (0.5, 0.6, 0.8)\\nfill_light.data.size = 4.0\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\n\\n# Subtle warm rim from behind-right to separate objects\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\nrim_light = bpy.context.active_object\\nrim_light.name = \\\"RimLight_Warm\\\"\\nrim_light.data.energy = 40\\nrim_light.data.color = (1.0, 0.75, 0.4)\\nrim_light.data.size = 2.0\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\n\\n# --- 2. Add a window frame to create light shaft pattern ---\\n# Window frame (dark wood, partially visible on left)\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\nwindow_frame = bpy.context.active_object\\nwindow_frame.name = \\\"WindowFrame\\\"\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\n\\n# Assign dark wood material\\nwindow_frame.data.materials.append(bpy.data.materials[\\\"M_TableTop\\\"])\\n\\n# --- 3. Adjust camera for better composition ---\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.5, -4.0, 2.0)\\ntarget = Vector((-0.1, 0.0, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Lighting and camera refined.\\\")\\nresult = {\\\"lights\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a6b2fe3e89402cda", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"lights\": [\n      \"FillLight_Dim\",\n      \"KeyLight_WarmShaft\",\n      \"RimLight_Warm\"\n    ]\n  },\n  \"stdout\": \"Lighting and camera refined.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-938e608ed2771955", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview with improved lighting\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.cycles.use_denoising = True\\nscene.render.filepath = \\\"C:/tmp/still_life_preview3.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze the result\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview3.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(f\\\"Image: {w}x{h}\\\")\\nprint(\\\"\\\\nBrightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-938e608ed2771955", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Image: 1536x1536\\n\\nBrightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |· · • ○ ○       |\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8421787e6475ccad", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8421787e6475ccad", "content": ""}, {"role": "assistant", "content": "The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.", "tool_calls": [{"id": "chatcmpl-tool-bf8158560fd480f6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\n# ============================================================\\nmat, nt = create_material(\\\"M_TeapotSilver\\\")\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\n\\n# Silver-ish base with warm ceramic undertones\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\nbsdf.inputs['Metallic'].default_value = 0.7\\nbsdf.inputs['Roughness'].default_value = 0.22\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Color variation: silver to warmer bronze areas\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 6.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Metallic variation\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\n\\n# Subtle surface bump for aged feel\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\nbump.inputs['Strength'].default_value = 0.1\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\nnoise3.inputs['Scale'].default_value = 60.0\\nnoise3.inputs['Detail'].default_value = 8.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\n# Assign to all teapot parts\\nfor name in [\\\"TeapotBody\\\", \\\"TeapotSpout\\\", \\\"TeapotHandle\\\", \\\"TeapotLid\\\"]:\\n    obj = bpy.data.objects[name]\\n    obj.data.materials.clear()\\n    obj.data.materials.append(mat)\\n\\n# Remove old material\\nold = bpy.data.materials.get(\\\"M_TeapotCeramic\\\")\\nif old:\\n    bpy.data.materials.remove(old)\\n\\nprint(\\\"Teapot silver material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf8158560fd480f6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Teapot silver material improved.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ae3e4ac817118e18", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE WINE GLASS: Add red wine inside\\n# ============================================================\\n# Create a separate wine liquid mesh inside the glass\\nimport bmesh\\n\\nmesh = bpy.data.meshes.new(\\\"WineLiquidMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\nwine_profile = [\\n    (0.00, 0.30),    # center bottom\\n    (0.06, 0.30),    # \\n    (0.08, 0.31),    # \\n    (0.10, 0.32),    # \\n    (0.11, 0.34),    # bowl\\n    (0.12, 0.36),    # \\n    (0.125, 0.38),   # \\n    (0.12, 0.40),    # \\n    (0.11, 0.42),    # \\n    (0.10, 0.44),    # wine surface level\\n    (0.00, 0.44),    # center top (wine surface)\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in wine_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = wine_profile[ri]\\n    rb, _ = wine_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            # Cap the top (wine surface)\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwine_obj = bpy.data.objects.new(\\\"WineLiquid\\\", mesh)\\nbpy.context.scene.collection.objects.link(wine_obj)\\nwine_obj.location = bpy.data.objects[\\\"WineGlass\\\"].location.copy()\\nwine_obj.scale = bpy.data.objects[\\\"WineGlass\\\"].scale.copy()\\nwine_obj.rotation_euler = bpy.data.objects[\\\"WineGlass\\\"].rotation_euler.copy()\\n\\n# Wine material - deep red, slightly translucent\\nmat, nt = create_material(\\\"M_RedWine\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.1\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\nbsdf.inputs['IOR'].default_value = 1.33\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nwine_obj.data.materials.append(mat)\\n\\nprint(\\\"Wine liquid added to glass.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ae3e4ac817118e18", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Wine liquid added to glass.\\n\"\n}"}, {"role": "assistant", "content": "Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.", "tool_calls": [{"id": "chatcmpl-tool-bf5e612aba0a0b79", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(7)\\n\\n# ============================================================\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\n# ============================================================\\n\\n# Rebuild the red cloth with better draping (hanging off table edge)\\nred_cloth = bpy.data.objects[\\\"RedCloth\\\"]\\n# Remove and rebuild\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\nmat_red = bpy.data.materials[\\\"M_RedVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"RedClothMesh\\\")\\nbm = bmesh.new()\\n\\n# Create a cloth that drapes over the left edge of the table\\n# Grid of vertices\\ncols = 50\\nrows = 40\\nwidth = 3.5\\nlength = 3.5\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\n        # and has ripple folds on the table surface\\n        if y < -0.5:\\n            # Hanging down over the edge\\n            edge_dist = abs(y + 0.5)\\n            z = -edge_dist * 0.8\\n            # Add vertical folds in the hanging part\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\n        else:\\n            # On the table: gentle ripples\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\n            z += 0.015 * math.cos(y * 8)\\n        \\n        # Add noise for natural variation\\n        z += random.uniform(-0.01, 0.01)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\n# Create faces\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nred_cloth = bpy.data.objects.new(\\\"RedCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(red_cloth)\\nred_cloth.location = (-1.8, -0.3, 0.01)\\nbpy.context.view_layer.objects.active = red_cloth\\nbpy.ops.object.shade_smooth()\\n\\n# Add solidify\\nmod = red_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\n# Add subsurf for smoothness\\nmod2 = red_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nred_cloth.data.materials.append(mat_red)\\n\\nprint(\\\"Red cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-bf5e612aba0a0b79", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-90e8b33148374071", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(8)\\n\\n# Rebuild green cloth with better draping\\ngreen_cloth = bpy.data.objects[\\\"GreenCloth\\\"]\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\nmat_green = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"GreenClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 40\\nwidth = 3.0\\nlength = 3.0\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Green cloth on right side, draped with folds\\n        # The back part rises slightly (against the wall)\\n        if y > 0.8:\\n            z = (y - 0.8) * 0.3\\n        else:\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\n            z += 0.015 * math.cos(y * 7)\\n        \\n        z += random.uniform(-0.008, 0.008)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\ngreen_cloth = bpy.data.objects.new(\\\"GreenCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(green_cloth)\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\nbpy.context.view_layer.objects.active = green_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = green_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.012\\nmod.offset = 0\\n\\nmod2 = green_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\ngreen_cloth.data.materials.append(mat_green)\\n\\nprint(\\\"Green cloth rebuilt with better draping.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-90e8b33148374071", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Green cloth rebuilt with better draping.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-957c0db57cb79a8e", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nimport random\\nfrom mathutils import Vector\\n\\nrandom.seed(9)\\n\\n# Rebuild white/neutral linen runner\\nwhite_cloth = bpy.data.objects[\\\"WhiteCloth\\\"]\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\nmat_white = bpy.data.materials[\\\"M_WhiteLinen\\\"]\\n\\nmesh = bpy.data.meshes.new(\\\"WhiteClothMesh\\\")\\nbm = bmesh.new()\\n\\ncols = 40\\nrows = 35\\nwidth = 2.5\\nlength = 2.2\\n\\nverts_grid = []\\nfor ri in range(rows + 1):\\n    row = []\\n    for ci in range(cols + 1):\\n        x = (ci / cols - 0.5) * width\\n        y = (ri / rows - 0.5) * length\\n        z = 0.0\\n        \\n        # Linen runner with subtle folds\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\n        z += 0.01 * math.cos(y * 6)\\n        # Slight droop at front edge\\n        if y < -0.7:\\n            z -= (abs(y) - 0.7) * 0.3\\n        \\n        z += random.uniform(-0.005, 0.005)\\n        \\n        v = bm.verts.new((x, y, z))\\n        row.append(v)\\n    verts_grid.append(row)\\n\\nfor ri in range(rows):\\n    for ci in range(cols):\\n        v1 = verts_grid[ri][ci]\\n        v2 = verts_grid[ri][ci+1]\\n        v3 = verts_grid[ri+1][ci+1]\\n        v4 = verts_grid[ri+1][ci]\\n        bm.faces.new([v1, v2, v3, v4])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nwhite_cloth = bpy.data.objects.new(\\\"WhiteCloth\\\", mesh)\\nbpy.context.scene.collection.objects.link(white_cloth)\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\nbpy.context.view_layer.objects.active = white_cloth\\nbpy.ops.object.shade_smooth()\\n\\nmod = white_cloth.modifiers.new(\\\"Solidify\\\", 'SOLIDIFY')\\nmod.thickness = 0.008\\nmod.offset = 0\\n\\nmod2 = white_cloth.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod2.levels = 1\\nmod2.render_levels = 2\\n\\nwhite_cloth.data.materials.append(mat_white)\\n\\nprint(\\\"White linen cloth rebuilt.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-957c0db57cb79a8e", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"White linen cloth rebuilt.\\n\"\n}"}, {"role": "assistant", "content": "Now let me render a preview to check the improved composition.", "tool_calls": [{"id": "chatcmpl-tool-8f408822e950583f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview4.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\n# Analyze\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview4.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (8x8 grid):\\\")\\nfor gy in range(8):\\n    row = \\\"\\\"\\n    for gx in range(8):\\n        x1 = gx * w // 8\\n        x2 = (gx+1) * w // 8\\n        y1 = gy * h // 8\\n        y2 = (gy+1) * h // 8\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 20):\\n            for x in range(x1, x2, 20):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.08: row += \\\"  \\\"\\n        elif bright < 0.15: row += \\\"· \\\"\\n        elif bright < 0.25: row += \\\"• \\\"\\n        elif bright < 0.35: row += \\\"○ \\\"\\n        elif bright < 0.45: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8f408822e950583f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (8x8 grid):\\n  Row 0: |· ·     · • • · |\\n  Row 1: |·   • ○ ○ •     |\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-82aa10aa5a9e7a68", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-82aa10aa5a9e7a68", "content": ""}, {"role": "assistant", "content": "Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.", "tool_calls": [{"id": "chatcmpl-tool-b4fbfa633bfd27a6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\n# Teapot is hero (center), overlapping depth arrangement\\n# ============================================================\\n\\n# Teapot - hero, center, commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.1, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\nteapot.scale = (0.9, 0.9, 0.9)\\n\\n# Stanford Bunny - left of teapot, slightly behind\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.1, 0.3, 0.03)\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\nbunny.scale = (1.2, 1.2, 1.2)\\n\\n# Suzanne - right side, as bust portrait gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.1, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\n\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Checkered sphere - front-center, slightly to right of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.3, -0.7, 0.22)\\n\\n# Wine glass - far right, behind Suzanne\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.7, 0.5, 0.0)\\nglass.scale = (1.1, 1.1, 1.1)\\n\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\nwine.scale = glass.scale.copy()\\n\\n# Open book - left-front, partially under bunny\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.5, -0.8, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(20))\\n\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit cluster - front-right, near Suzanne\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.9, -0.8, 0.09)\\nbpy.data.objects[\\\"Orange1\\\"].rotation_euler = (0, 0, math.radians(30))\\n\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.1, -0.7, 0.075)\\nbpy.data.objects[\\\"Orange2\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\n\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.75, -0.65, 0.08)\\nbpy.data.objects[\\\"Lemon1\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\n\\n# Camera - slightly elevated, 50mm equivalent\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.2, -4.2, 2.0)\\ntarget = Vector((0.1, -0.1, 0.35))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\nprint(\\\"Objects repositioned for composition.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-b4fbfa633bfd27a6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Objects repositioned for composition.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-91bf4a1a9b72901d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check composition\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview5.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-91bf4a1a9b72901d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |· · ·       · · • • |\\n  Row 1: |• ·   · • ○ ○ • • • |\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": "The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.", "tool_calls": [{"id": "chatcmpl-tool-a3cf445099275d43", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a3cf445099275d43", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8805a99244b0b994", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Let me check the image more carefully by saving a smaller version\\n# and examining color distribution\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview5.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis: check for red, green, and neutral areas\\nred_count = 0\\ngreen_count = 0\\nneutral_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    # Red dominant\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    # Green dominant\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\n        green_count += 1\\n    # Warm (yellow/orange)\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n    # Neutral\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\n        neutral_count += 1\\n\\nprint(f\\\"Total visible pixels: {total}\\\")\\nprint(f\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\")\\nprint(f\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\")\\nprint(f\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\")\\nprint(f\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\")\\n\\n# Check if teapot is visible (bright metallic highlights)\\nbright_metallic = 0\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\n        bright_metallic += 1\\nprint(f\\\"\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8805a99244b0b994", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Total visible pixels: 2359296\\nRed dominant: 483000 (20.5%)\\nGreen dominant: 156 (0.0%)\\nWarm (yellow/orange): 1029663 (43.6%)\\nNeutral: 88690 (3.8%)\\n\\nBright metallic highlights: 172218 (7.3%)\\n\"\n}"}, {"role": "assistant", "content": "I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.", "tool_calls": [{"id": "chatcmpl-tool-81b0f5052b6b4974", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\n# ============================================================\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\n# The green needs to be more visible facing the red\\n# ============================================================\\n\\n# Make the green panel larger and more prominent on the right\\ngreen_panel = bpy.data.objects[\\\"GreenPanel\\\"]\\ngreen_panel.location = (2.5, 1.5, 1.8)\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\ngreen_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Make the red panel larger too\\nred_panel = bpy.data.objects[\\\"RedPanel\\\"]\\nred_panel.location = (-2.5, 1.5, 1.8)\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\nred_panel.scale = (3.0, 4.0, 1)\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\n\\n# Brighten the green panel material slightly so it reads\\nmat_green_panel = bpy.data.materials[\\\"M_GreenPanel\\\"]\\nnt = mat_green_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\n\\n# Also make the red panel slightly brighter\\nmat_red_panel = bpy.data.materials[\\\"M_RedPanel\\\"]\\nnt = mat_red_panel.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\n\\n# Make the green velvet cloth brighter too\\nmat_green_velvet = bpy.data.materials[\\\"M_GreenVelvet\\\"]\\nnt = mat_green_velvet.node_tree\\nbsdf = nt.nodes['Principled BSDF']\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\n\\n# Update the color ramp in green velvet\\nfor node in nt.nodes:\\n    if node.type == 'VALTORGB':\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\n\\nprint(\\\"Cornell palette balanced.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-81b0f5052b6b4974", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Cornell palette balanced.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-a4b7c915f2deeb2b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Quick render to check color balance\\nscene = bpy.context.scene\\nscene.cycles.samples = 24\\nscene.render.filepath = \\\"C:/tmp/still_life_preview6.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview6.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Color analysis\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    \\n    if brightness < 0.05:\\n        continue\\n    \\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red dominant: {100*red_count/total:.1f}%\\\")\\nprint(f\\\"Green dominant: {100*green_count/total:.1f}%\\\")\\nprint(f\\\"Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check right side specifically for green\\nright_green = 0\\nright_total = 0\\nfor y in range(h):\\n    for x in range(w * 2 // 3, w):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_total += 1\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\n                right_green += 1\\nprint(f\\\"Right side green: {100*right_green/right_total:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a4b7c915f2deeb2b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red dominant: 14.0%\\nGreen dominant: 3.8%\\nWarm: 31.4%\\nRight side green: 9.8%\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9f686bd02109d814", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9f686bd02109d814", "content": ""}, {"role": "assistant", "content": "The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.", "tool_calls": [{"id": "chatcmpl-tool-ad7552f450a30efc", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# ============================================================\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_CheckeredSphere\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\n\\n# Perfect mirror chrome with checker pattern\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\n\\n# Checker pattern using texture coordinate\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\nchecker.inputs['Scale'].default_value = 8.0\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\n\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Checkered sphere material improved - true reflective chrome.\\\")\\n\\n# ============================================================\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\n# ============================================================\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\nfor n in list(nt.nodes):\\n    nt.nodes.remove(n)\\n\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\nbsdf.inputs['Roughness'].default_value = 0.25\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\n\\n# Marble veining using noise and wave\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\n\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\nnoise.inputs['Scale'].default_value = 3.0\\nnoise.inputs['Detail'].default_value = 3.0\\nnoise.inputs['Distortion'].default_value = 2.0\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\n\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\nwave.inputs['Scale'].default_value = 3.0\\nwave.inputs['Distortion'].default_value = 3.0\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\n\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\nmix.data_type = 'RGBA'\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\n\\n# Color ramp for veining\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\n# Subtle bump\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\nbump.inputs['Strength'].default_value = 0.08\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\nnoise3.inputs['Scale'].default_value = 100.0\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nprint(\\\"Suzanne marble material improved.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad7552f450a30efc", "content": "{\n  \"status\": \"error\",\n  \"message\": \"Traceback (most recent call last):\\n  File \\\"C:\\\\Users\\\\proud\\\\Downloads\\\\Telegram Desktop\\\\blender-bench-runner-windows\\\\.runner\\\\blender-mcp-v1.0.0\\\\addon\\\\mcp_to_blender_server.py\\\", line 230, in _execute_code\\n    exec(code, namespace)\\n    ~~~~^^^^^^^^^^^^^^^^^\\n  File \\\"<string>\\\", line 103, in <module>\\nKeyError: 'bpy_prop_collection[key]: key \\\"Base Color\\\" not found'\\n\",\n  \"stdout\": \"Checkered sphere material improved - true reflective chrome.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-88fb07aca4529ea6", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Remove the bad link\\nfor link in list(nt.links):\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\n        nt.links.remove(link)\\n        print(f\\\"Removed bad link from {link.from_node.name}\\\")\\n\\n# Verify the material works\\nprint(\\\"Suzanne material nodes:\\\")\\nfor node in nt.nodes:\\n    print(f\\\"  {node.name} ({node.type})\\\")\\n    \\nprint(\\\"\\\\nLinks:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-88fb07aca4529ea6", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Suzanne material nodes:\\n  Material Output (OUTPUT_MATERIAL)\\n  Principled BSDF (BSDF_PRINCIPLED)\\n  Texture Coordinate (TEX_COORD)\\n  Mapping (MAPPING)\\n  Noise Texture (TEX_NOISE)\\n  Wave Texture (TEX_WAVE)\\n  Mix (MIX)\\n  Color Ramp (VALTORGB)\\n  Bump (BUMP)\\n  Noise Texture.001 (TEX_NOISE)\\n\\nLinks:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9cddced158a16a7f", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Connect bump to BSDF Normal and BSDF to output\\nmat = bpy.data.materials.get(\\\"M_SuzanneMarble\\\")\\nnt = mat.node_tree\\n\\n# Make sure bump normal goes to BSDF\\nbump = None\\nbsdf = None\\noutput = None\\nfor node in nt.nodes:\\n    if node.type == 'BUMP':\\n        bump = node\\n    elif node.type == 'BSDF_PRINCIPLED':\\n        bsdf = node\\n    elif node.type == 'OUTPUT_MATERIAL':\\n        output = node\\n\\nif bump and bsdf:\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\n    print(\\\"Connected bump to BSDF Normal\\\")\\n\\nif bsdf and output:\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n    print(\\\"Connected BSDF to output\\\")\\n\\nprint(\\\"\\\\nFinal links:\\\")\\nfor link in nt.links:\\n    print(f\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9cddced158a16a7f", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Connected bump to BSDF Normal\\nConnected BSDF to output\\n\\nFinal links:\\n  Texture Coordinate.Generated -> Mapping.Vector\\n  Mapping.Vector -> Noise Texture.Vector\\n  Mapping.Vector -> Wave Texture.Vector\\n  Wave Texture.Color -> Mix.A\\n  Noise Texture.Color -> Mix.B\\n  Mix.Result -> Color Ramp.Factor\\n  Color Ramp.Color -> Principled BSDF.Base Color\\n  Noise Texture.001.Factor -> Bump.Height\\n  Bump.Normal -> Principled BSDF.Normal\\n  Principled BSDF.BSDF -> Material Output.Surface\\n\"\n}"}, {"role": "assistant", "content": "Good, Suzanne material is fixed. Now let me render to check everything looks good.", "tool_calls": [{"id": "chatcmpl-tool-a1bde82900051568", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview7.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.5: row += \\\"▓ \\\"\\n        elif bright < 0.65: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-a1bde82900051568", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▒ ● ·             |\\n  Row 4: |█ ▒ ● ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-8bf5081c37eebeb6", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-8bf5081c37eebeb6", "content": ""}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-96f3c02259f22638", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Check the right side of the image for green\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview7.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\n# Detailed color check on the right portion\\nred_count = 0\\ngreen_count = 0\\nwarm_count = 0\\ntotal = 0\\n\\nfor i in range(0, len(pixels), 4):\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\n    total += 1\\n    brightness = (r + g + b) / 3\\n    if brightness < 0.05:\\n        continue\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\n        red_count += 1\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\n        green_count += 1\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\n        warm_count += 1\\n\\nprint(f\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\")\\n\\n# Check the right side specifically\\nright_g = 0\\nright_t = 0\\nfor y in range(h):\\n    for x in range(int(w*0.7), w, 3):\\n        idx = (y * w + x) * 4\\n        if idx + 2 < len(pixels):\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\n            right_t += 1\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\n                right_g += 1\\nprint(f\\\"Right side green: {100*right_g/right_t:.1f}%\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-96f3c02259f22638", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\nRight side green: 10.8%\\n\"\n}"}, {"role": "assistant", "content": "Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.", "tool_calls": [{"id": "chatcmpl-tool-99ced8845b19cf57", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport bmesh\\nimport math\\nfrom mathutils import Vector\\n\\ndef link_obj(obj):\\n    bpy.context.scene.collection.objects.link(obj)\\n    return obj\\n\\n# ============================================================\\n# CANDLESTICK with candle - additional classical prop\\n# Justifies the warm light source\\n# ============================================================\\nmesh = bpy.data.meshes.new(\\\"CandlestickMesh\\\")\\nbm = bmesh.new()\\n\\n# Profile of the candlestick (radius, height) — lathed\\nstick_profile = [\\n    (0.00, 0.00),    # center bottom\\n    (0.12, 0.00),    # base edge\\n    (0.13, 0.01),    # base lip\\n    (0.12, 0.03),    # \\n    (0.08, 0.04),    # base to stem\\n    (0.05, 0.06),    # stem base\\n    (0.04, 0.15),    # stem\\n    (0.04, 0.25),    # stem\\n    (0.05, 0.30),    # mid decorative\\n    (0.04, 0.35),    # \\n    (0.035, 0.40),   # upper stem\\n    (0.05, 0.44),    # candle cup base\\n    (0.06, 0.46),    # cup\\n    (0.055, 0.48),   # cup lip\\n    (0.04, 0.50),    # cup inner\\n    (0.00, 0.50),    # center top\\n]\\n\\nsegments = 48\\nall_verts = []\\nfor r, h in stick_profile:\\n    ring = []\\n    if r < 0.001:\\n        v = bm.verts.new((0, 0, h))\\n        ring = [v] * segments\\n    else:\\n        for i in range(segments):\\n            angle = (i / segments) * math.tau\\n            x = r * math.cos(angle)\\n            y = r * math.sin(angle)\\n            v = bm.verts.new((x, y, h))\\n            ring.append(v)\\n    all_verts.append(ring)\\n\\nbm.verts.ensure_lookup_table()\\n\\nfor ri in range(len(all_verts) - 1):\\n    ring_a = all_verts[ri]\\n    ring_b = all_verts[ri + 1]\\n    ra, _ = stick_profile[ri]\\n    rb, _ = stick_profile[ri + 1]\\n    for i in range(segments):\\n        j = (i + 1) % segments\\n        if ra < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\n        elif rb < 0.001:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\n        else:\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\n\\nbm.normal_update()\\nbm.to_mesh(mesh)\\nbm.free()\\n\\nstick_obj = bpy.data.objects.new(\\\"Candlestick\\\", mesh)\\nlink_obj(stick_obj)\\nstick_obj.location = (-1.6, 0.8, 0.0)\\nbpy.context.view_layer.objects.active = stick_obj\\nbpy.ops.object.shade_smooth()\\n\\nmod = stick_obj.modifiers.new(\\\"Subsurf\\\", 'SUBSURF')\\nmod.levels = 1\\nmod.render_levels = 2\\n\\n# Candle\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\ncandle = bpy.context.active_object\\ncandle.name = \\\"Candle\\\"\\nbpy.ops.object.shade_smooth()\\n\\n# Candle flame - a small emissive shape\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\nflame = bpy.context.active_object\\nflame.name = \\\"CandleFlame\\\"\\nflame.scale = (0.6, 0.6, 1.8)\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\nbpy.ops.object.shade_smooth()\\n\\nprint(\\\"Candlestick with candle and flame built.\\\")\\nresult = {\\\"candlestick\\\": stick_obj.name, \\\"candle\\\": candle.name, \\\"flame\\\": flame.name}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-99ced8845b19cf57", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"candlestick\": \"Candlestick\",\n    \"candle\": \"Candle\",\n    \"flame\": \"CandleFlame\"\n  },\n  \"stdout\": \"Candlestick with candle and flame built.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-86253733bb060d5b", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\n\\ndef create_material(name):\\n    mat = bpy.data.materials.new(name)\\n    mat.use_nodes = True\\n    nt = mat.node_tree\\n    for n in list(nt.nodes):\\n        nt.nodes.remove(n)\\n    return mat, nt\\n\\ndef add_node(nt, node_type, location=(0,0)):\\n    n = nt.nodes.new(node_type)\\n    n.location = location\\n    return n\\n\\n# --- Candlestick: Aged brass/bronze ---\\nmat, nt = create_material(\\\"M_CandlestickBrass\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\nbsdf.inputs['Metallic'].default_value = 1.0\\nbsdf.inputs['Roughness'].default_value = 0.35\\n\\n# Patina variation\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\nnoise.inputs['Scale'].default_value = 5.0\\nnoise.inputs['Detail'].default_value = 4.0\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\n\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\nbump.inputs['Strength'].default_value = 0.2\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\nnoise2.inputs['Scale'].default_value = 40.0\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\n\\nbpy.data.objects[\\\"Candlestick\\\"].data.materials.append(mat)\\n\\n# --- Candle: Waxed off-white ---\\nmat, nt = create_material(\\\"M_Candle\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\nbsdf.inputs['Roughness'].default_value = 0.5\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\nbpy.data.objects[\\\"Candle\\\"].data.materials.append(mat)\\n\\n# --- Candle flame: Emissive ---\\nmat, nt = create_material(\\\"M_CandleFlame\\\")\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\nemission.inputs['Strength'].default_value = 15.0\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\nbpy.data.objects[\\\"CandleFlame\\\"].data.materials.append(mat)\\n\\n# Add a point light at the flame for actual illumination\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\nflame_light = bpy.context.active_object\\nflame_light.name = \\\"CandleLight\\\"\\nflame_light.data.energy = 50\\nflame_light.data.color = (1.0, 0.7, 0.3)\\nflame_light.data.shadow_soft_size = 0.05\\n\\nprint(\\\"Candlestick, candle, and flame materials created.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-86253733bb060d5b", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Candlestick, candle, and flame materials created.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ad276f7e043b8f86", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render with candle\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview8.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview8.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (10x10 grid):\\\")\\nfor gy in range(10):\\n    row = \\\"\\\"\\n    for gx in range(10):\\n        x1 = gx * w // 10\\n        x2 = (gx+1) * w // 10\\n        y1 = gy * h // 10\\n        y2 = (gy+1) * h // 10\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 25):\\n            for x in range(x1, x2, 25):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ad276f7e043b8f86", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (10x10 grid):\\n  Row 0: |  · ·         · · · |\\n  Row 1: |• ·     · • • · ·   |\\n  Row 2: |· • ○ • ·           |\\n  Row 3: |▓ ▓ ● ·             |\\n  Row 4: |▒ ▒ ▓ ·             |\\n  Row 5: |▓ ● ▓ ● ● ·         |\\n  Row 6: |  ● ▒ ▒ ▒ ▓ ▓ ○ •   |\\n  Row 7: |● █ █ █ ▒ ▒ ▒ ▒ ▓ ▓ |\\n  Row 8: |█ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\n  Row 9: |▒ █ █ █ █ █ █ ▒ ▒ ▓ |\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-ac68c75cb6cd7431", "type": "function", "function": {"name": "get_screenshot_of_area_as_image", "arguments": "{\"area_ui_type\": \"VIEW_3D\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-ac68c75cb6cd7431", "content": ""}, {"role": "assistant", "content": "The composition is looking good. Let me make some final adjustments: I want to ensure the table edge is visible in the lower frame, and that the objects are well-grouped with overlapping depth. Let me also add a few more details to sell the Dutch Golden Age look.", "tool_calls": [{"id": "chatcmpl-tool-880e723bea6f81d2", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\nimport math\\nfrom mathutils import Vector\\n\\n# ============================================================\\n# FINAL COMPOSITION ADJUSTMENTS\\n# ============================================================\\n\\n# Adjust camera to see table edge in lower frame and get better angle\\ncam = bpy.data.objects[\\\"Camera_Presentation\\\"]\\ncam.location = (3.0, -3.5, 1.8)\\ntarget = Vector((0.1, -0.1, 0.3))\\ndirection = target - cam.location\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\ncam.rotation_euler = rot_quat.to_euler()\\ncam.data.dof.focus_distance = (cam.location - target).length\\n\\n# Adjust teapot position to be more centered and commanding\\nteapot = bpy.data.objects[\\\"UtahTeapot\\\"]\\nteapot.location = (0.0, 0.0, 0.0)\\nteapot.rotation_euler = (0, 0, math.radians(-15))\\nteapot.scale = (0.95, 0.95, 0.95)\\n\\n# Bunny slightly closer and turned toward camera\\nbunny = bpy.data.objects[\\\"StanfordBunny\\\"]\\nbunny.location = (-1.0, 0.2, 0.03)\\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\\nbunny.scale = (1.15, 1.15, 1.15)\\n\\n# Suzanne on right, gazing out\\nsuzanne = bpy.data.objects[\\\"Suzanne\\\"]\\nsuzanne.location = (1.0, -0.1, 0.2)\\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\\nbase = bpy.data.objects[\\\"SuzanneBase\\\"]\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\n\\n# Sphere more centered, in front of teapot\\nsphere = bpy.data.objects[\\\"CheckeredSphere\\\"]\\nsphere.location = (0.2, -0.65, 0.22)\\n\\n# Wine glass moved slightly\\nglass = bpy.data.objects[\\\"WineGlass\\\"]\\nglass.location = (1.65, 0.4, 0.0)\\nwine = bpy.data.objects[\\\"WineLiquid\\\"]\\nwine.location = glass.location.copy()\\n\\n# Candlestick on left, behind bunny\\nstick = bpy.data.objects[\\\"Candlestick\\\"]\\nstick.location = (-1.7, 0.9, 0.0)\\ncandle = bpy.data.objects[\\\"Candle\\\"]\\ncandle.location = (-1.7, 0.9, 0.575)\\nflame = bpy.data.objects[\\\"CandleFlame\\\"]\\nflame.location = (-1.7, 0.9, 0.70)\\nflame_light = bpy.data.objects[\\\"CandleLight\\\"]\\nflame_light.location = (-1.7, 0.9, 0.72)\\n\\n# Book\\nbook = bpy.data.objects[\\\"OpenBook\\\"]\\nbook.location = (-0.4, -0.85, 0.02)\\nbook.rotation_euler = (0, 0, math.radians(25))\\ncover = bpy.data.objects[\\\"BookCover\\\"]\\ncover.location = book.location.copy()\\ncover.rotation_euler = book.rotation_euler.copy()\\n\\n# Fruit\\nbpy.data.objects[\\\"Orange1\\\"].location = (0.8, -0.85, 0.09)\\nbpy.data.objects[\\\"Orange2\\\"].location = (1.0, -0.75, 0.075)\\nbpy.data.objects[\\\"Lemon1\\\"].location = (0.65, -0.7, 0.08)\\n\\nprint(\\\"Final composition adjustments made.\\\")\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-880e723bea6f81d2", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Final composition adjustments made.\\n\"\n}"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "chatcmpl-tool-9ab206cfd8c4ba5d", "type": "function", "function": {"name": "execute_blender_code", "arguments": "{\"code\": \"\\nimport bpy\\n\\n# Render preview\\nscene = bpy.context.scene\\nscene.cycles.samples = 32\\nscene.render.filepath = \\\"C:/tmp/still_life_preview9.png\\\"\\nbpy.ops.render.render(write_still=True)\\n\\nimg = bpy.data.images.load(\\\"C:/tmp/still_life_preview9.png\\\")\\nw, h = img.size[0], img.size[1]\\npixels = list(img.pixels)\\n\\nprint(\\\"Brightness map (12x12 grid):\\\")\\nfor gy in range(12):\\n    row = \\\"\\\"\\n    for gx in range(12):\\n        x1 = gx * w // 12\\n        x2 = (gx+1) * w // 12\\n        y1 = gy * h // 12\\n        y2 = (gy+1) * h // 12\\n        bright_sum = 0\\n        count = 0\\n        for y in range(y1, y2, 30):\\n            for x in range(x1, x2, 30):\\n                idx = (y * w + x) * 4\\n                if idx + 2 < len(pixels):\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\n                    count += 1\\n        bright = bright_sum / count if count > 0 else 0\\n        if bright < 0.06: row += \\\"  \\\"\\n        elif bright < 0.12: row += \\\"· \\\"\\n        elif bright < 0.2: row += \\\"• \\\"\\n        elif bright < 0.3: row += \\\"○ \\\"\\n        elif bright < 0.4: row += \\\"● \\\"\\n        elif bright < 0.55: row += \\\"▓ \\\"\\n        elif bright < 0.7: row += \\\"▒ \\\"\\n        else: row += \\\"█ \\\"\\n    print(f\\\"  Row {gy}: |{row}|\\\")\\n\\nresult = {\\\"status\\\": \\\"ok\\\"}\\n\"}"}}]}, {"role": "tool", "tool_call_id": "chatcmpl-tool-9ab206cfd8c4ba5d", "content": "{\n  \"status\": \"ok\",\n  \"result\": {\n    \"status\": \"ok\"\n  },\n  \"stdout\": \"Brightness map (12x12 grid):\\n  Row 0: |· ·       · • • • • ·   |\\n  Row 1: |•     • ○ ○ • ·         |\\n  Row 2: |  • ● ○ • ·             |\\n  Row 3: |▓ ▓ ○                   |\\n  Row 4: |▒ ▒ ● •                 |\\n  Row 5: |▒ ▒ ▓ · ·               |\\n  Row 6: |▒ ▓ ● ○ •               |\\n  Row 7: |○ ● ▒ ▓ █ ▒ ● • ·       |\\n  Row 8: |  ▒ ▒ ▒ ▒ ▒ ▓ ▒ ▓ ● ○ · |\\n  Row 9: |▓ █ █ █ █ ▒ ▒ ▒ ▒ ▒ ▒ ▓ |\\n  Row 10: |█ █ █ █ █ █ ▒ ▒ ▒ ▒ ▒ ▒ |\\n  Row 11: |█ █ █ █ █ █ █ █ █ ▒ ▒ ▒ |\\n\"\n}"}], "tools": [{"type": "function", "function": {"name": "execute_blender_code", "description": "\n        Execute Python code in the connected Blender instance.\n\n        The code runs in Blender's Python environment with full access to ``bpy``.\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\n        Deferred completion via ``check_is_finished`` is only supported by the\n        interactive addon server, and is rejected in background mode.\n        ", "parameters": {"properties": {"code": {"title": "Code", "type": "string"}}, "required": ["code"], "title": "execute_blender_codeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "execute_blender_code_for_cli", "description": "\n        Execute Python code in a background Blender process.\n\n        Opens *blend_file* with ``blender --background`` and runs *code*.\n        Assign a dict to ``result`` to return data.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}, "code": {"title": "Code", "type": "string"}}, "required": ["blend_file", "code"], "title": "execute_blender_code_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks", "description": "\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_datablocksArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_datablocks_for_cli", "description": "\n        Return a data-block summary by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_datablocks_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files", "description": "\n        Report external file references that are missing from disk\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_missing_filesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_missing_files_for_cli", "description": "\n        Report missing file references by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_missing_files_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries", "description": "\n        Return a tree of directly and indirectly linked library files.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_of_linked_librariesArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_of_linked_libraries_for_cli", "description": "\n        Return linked-library info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_of_linked_libraries_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info", "description": "\n        Simple/fast access to the blend file's path, save status, age, and backups.\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_path_infoArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_path_info_for_cli", "description": "\n        Return path info by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_path_info_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess", "description": "\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\n        ", "parameters": {"properties": {}, "title": "get_blendfile_summary_usage_guessArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_blendfile_summary_usage_guess_for_cli", "description": "\n        Guess use-cases by opening *blend_file* in background Blender.\n        ", "parameters": {"properties": {"blend_file": {"title": "Blend File", "type": "string"}}, "required": ["blend_file"], "title": "get_blendfile_summary_usage_guess_for_cliArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_object_detail_summary", "description": "\n        Return a structured summary of the object identified by *name*.\n\n        Includes type, transforms, parent, children, modifiers, constraints,\n        materials, visibility, data-block name, and collections.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "get_object_detail_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_objects_summary", "description": "\n        Return the scene's collection hierarchy and their objects.\n\n        Each collection lists its objects (name, type, parent, data name,\n        selection, visibility) and nested child collections.\n        ", "parameters": {"properties": {}, "title": "get_objects_summaryArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_python_api_docs", "description": "\n        Return the Blender Python API docs for *identifier*, or list\n        modules matching a trailing-``*`` discovery pattern.\n\n        *identifier* should be a fully-qualified Python name (e.g.\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\n        The trailing-``*`` forms are supported as discovery entry-points:\n\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\n          ``mathutils``, ``gpu``, ...).\n        - ``X.*`` enumerates the direct-child identifiers under the\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\n\n        Both return a ``namespace`` response even when ``X.rst`` would\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\n        force the child listing.\n\n        The response always carries ``kind``, ``found``, and ``identifier``.\n        The remaining keys depend on ``kind``:\n\n        - ``\"exact\"`` (``found=True``): ``<identifier>.rst`` was read.\n          Extra keys: ``content`` (RST text), ``examples``. When the\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\n          summary of the file's top-level definitions (prefixed by a\n          header noting the truncation) and ``examples`` is empty -\n          re-query individual members for their rendered blocks.\n        - ``\"namespace\"`` (``found=True``):\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\n          Extra key: ``submodules`` (list of child identifiers).\n        - ``\"definition\"`` (``found=True``):\n          *identifier* is defined inside a parent RST\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\n          Extra keys: ``content`` (rendered block), ``examples``.\n        - ``\"partial\"`` (``found=False``):\n          the parent RST was located but the trailing component isn't defined in it.\n          Extra keys:\n          - ``parent`` the identifier whose RST was loaded.\n          - ``available`` top-level definitions in that RST.\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\n            filtered to those whose last component contains every character of the missing tail.\n\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\n        - ``\"suggestions\"`` (``found=False``):\n          no direct match, but *identifier* appears as a component of other files.\n          Extra key: ``suggestions`` (list of full identifiers).\n        - ``\"missing\"`` (``found=False``): nothing matched.\n\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\n        is a list of ``{path, content}`` entries referenced from this documentation.\n        ", "parameters": {"properties": {"identifier": {"title": "Identifier", "type": "string"}}, "required": ["identifier"], "title": "get_python_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_area_as_image", "description": "\n        Take a screenshot of a single Blender area and return it as a PNG image.\n\n        *area_ui_type* matches the area's ``ui_type``.\n\n        *size_limit_in_bytes* caps the image size in bytes.\n        Zero (the default) uses the MCP message size limit.\n        ", "parameters": {"properties": {"area_ui_type": {"enum": ["VIEW_3D", "IMAGE_EDITOR", "UV", "ShaderNodeTree", "CompositorNodeTree", "GeometryNodeTree", "TextureNodeTree", "SEQUENCE_EDITOR", "CLIP_EDITOR", "DOPESHEET_EDITOR", "GRAPH_EDITOR", "NLA_EDITOR", "TEXT_EDITOR", "CONSOLE", "INFO", "TOPBAR", "STATUSBAR", "OUTLINER", "PROPERTIES", "FILE_BROWSER", "SPREADSHEET", "PREFERENCES"], "title": "Area Ui Type", "type": "string"}, "size_limit_in_bytes": {"default": 0, "title": "Size Limit In Bytes", "type": "integer"}}, "required": ["area_ui_type"], "title": "get_screenshot_of_area_as_imageArguments", "type": "object"}}}, {"type": "function", "function": {"name": "get_screenshot_of_window_as_json", "description": "\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\n        ", "parameters": {"properties": {}, "title": "get_screenshot_of_window_as_jsonArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_name", "description": "\n        Switch the active workspace tab to *name*.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "jump_to_tab_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_tab_by_space_type", "description": "\n        Switch to a workspace whose main area matches *space_type*.\n\n        If *allow_edits* is True and no matching workspace exists, a new one\n        is created by duplicating the current workspace.\n        ", "parameters": {"properties": {"space_type": {"title": "Space Type", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["space_type"], "title": "jump_to_tab_by_space_typeArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_by_name", "description": "\n        Move the 3D viewport to focus on an object by *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "jump_to_view3d_object_data_by_name", "description": "\n        Move the 3D viewport to the object whose data block matches *name*.\n\n        If *allow_edits* is True the object may be un-hidden and its\n        collections enabled to make it visible.\n        ", "parameters": {"properties": {"name": {"title": "Name", "type": "string"}, "allow_edits": {"default": false, "title": "Allow Edits", "type": "boolean"}}, "required": ["name"], "title": "jump_to_view3d_object_data_by_nameArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_thumbnail_to_path", "description": "\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_thumbnail_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "render_viewport_to_path", "description": "\n        Render the current scene to *output_path* using current render settings.\n        ", "parameters": {"properties": {"output_path": {"title": "Output Path", "type": "string"}}, "required": ["output_path"], "title": "render_viewport_to_pathArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_api_docs", "description": "\nFull-text search over the bundled Blender Python API reference.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_api_docsArguments", "type": "object"}}}, {"type": "function", "function": {"name": "search_manual_docs", "description": "\nFull-text search over the bundled Blender user manual.\n\nReturns a ranked list of hits. Each hit has:\n\n- ``path``: file path relative to the bundled docs.\n- ``text``: the matching paragraph plus ``context``\n  paragraphs on either side.\n- ``breadcrumb``: the section path containing the hit\n  (``Section > Sub-section > ...``).\n- ``index``: the hit's position in the result list.\n- ``score``: a relevance score; higher is better.\n\nThe query is tokenised on whitespace and matched\ncase-insensitively. Every token must appear somewhere in\nthe paragraph body, the file path, or an enclosing section\ntitle - in any order. Common English stop-words (``the``,\n``a``, ``how``, ``to``, ...) are dropped, so natural\nphrasings like ``\"how to bake\"`` work as expected. Regular\nexpressions are not supported.\n\nUse ``context`` to pull more surrounding paragraphs into\neach hit (symmetric, default 0). Use ``index`` with the\nposition of a previous hit (same query) to get that hit\nalone with its text widened to its enclosing section.\n\nRead-only; consults bundled RST files only.\n", "parameters": {"properties": {"query": {"title": "Query", "type": "string"}, "max_results": {"default": 20, "title": "Max Results", "type": "integer"}, "context": {"default": 0, "title": "Context", "type": "integer"}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Index"}}, "required": ["query"], "title": "search_manual_docsArguments", "type": "object"}}}]}, "provider_attempts": [{"provider": "openrouter", "attempt": 1, "started_at": "2026-07-17T15:21:35.838391+00:00", "finished_at": "2026-07-17T15:21:37.153426+00:00", "duration_s": 1.312000000005355, "request": {"method": "POST", "url": "https://openrouter.ai/api/v1/chat/completions", "headers": {"host": "openrouter.ai", "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "keep-alive", "user-agent": "python-httpx/0.28.1", "authorization": "[REDACTED]", "content-length": "202616", "content-type": "application/json"}, "body": "{\"model\":\"z-ai/glm-5.2\",\"messages\":[{\"role\":\"system\",\"content\":\"You are participating in Blender-Bench, a public benchmark where AI models complete the same Blender task.\\n\\nYour result will be compared head-to-head with another model. Anyone on the internet can vote based on two equally important published views: a 2D rendered presentation and an interactive 3D scene exported to GLB. Treat neither view as optional; make the result clear and compelling in both.\\n\\nComplete the request as well as you can. The benchmark does not prescribe a workflow or visual style; use whichever Blender techniques you consider appropriate. Make the important requirements evident in the published result, save a complete scene, and present the work clearly in every requested output.\\n\\nThe 2D presentation is rendered by the benchmark from your saved scene using Cycles at 1536 x 1536, 64 samples, denoising enabled, and GPU acceleration when available with a CPU fallback. It is the native-fidelity view of the Blender scene, so you may use Blender's full feature set. Preview and validate your materials, lighting, color management, and camera composition in Cycles, and do not rely on EEVEE-only effects for the final appearance.\\n\\nThe interactive 3D view is a best-effort GLB export containing geometry, compatible materials, the contestant camera, and supported lights. Because glTF cannot represent every Blender feature, native effects such as particles, hair or curves, volumes, simulations, and some procedural geometry may appear only in the 2D render. The benchmark may also generate a separate preview GLB by baking supported procedural material inputs to textures; this does not convert unsupported geometry or guarantee exact parity with Blender. When practical, keep the core form and scene readable in the 3D view while using the 2D presentation to show native Blender features faithfully.\\n\\n## Harness Instructions\\n\\nYou are operating Blender through the provided tools. Tool calls execute one at a time, in the order you issue them, against a single live Blender instance — each call sees the state left by the previous one, and issuing several calls in one message gains no parallelism. The scene starts empty. Build what the user's prompt asks for in the current scene. Work step by step and verify your own work.\\n\\nYou are building a real three-dimensional scene, and evaluators judge the whole scene and your final render side by side — an interactive 3D view and a benchmark-generated 360° camera orbit rendered in Cycles from your saved scene appear next to your presentation render, so forms that only read correctly from one angle will show. Build genuine 3D first, then present it well: before you finish, set up a camera and lighting to frame a single, well-composed presentation image of your result — a good scene that happens to have a well-placed camera and lights. The final benchmark capture overrides the scene render settings and renders in Cycles at 1536x1536, 64 samples, with denoising and GPU acceleration (CPU fallback). Preview and validate materials, lighting, color management, and composition in Cycles; do not rely on EEVEE-only effects. Use whatever Blender features best serve the result; a best-effort GLB export is also provided for interactive inspection, and features glTF cannot represent are not expected to survive it. When you are finished, reply with the single word DONE and no tool calls.\"},{\"role\":\"user\",\"content\":\"## Task\\n\\nComplete the following Blender task:\\n\\n<task>\\n\\nA classical still life in the Dutch Golden Age manner — dark ground, draped cloth, a shaft of warm light, objects arranged with deliberate care — except every object on the table is a monument of computer-graphics history. The twist must work in both directions: read as a museum-worthy still life at arm's length, and land as one long graphics in-joke on the second look.\\n\\nThe cast (required objects, all modeled in-scene — no imported meshes, no downloaded assets).\\n- The Utah Teapot, hero of the arrangement: the classic squat proportions with the familiar spout, handle, and lid. Give it an honest ceramic or silver-teapot material worthy of a Vermeer table.\\n- The Stanford Bunny, approximated: the recognizable compact crouched-rabbit silhouette with its rounded back and folded ears, at rest on the table like a sculpture. A faithful sculptural likeness of the pose is what counts, not vertex-level accuracy.\\n- Suzanne, Blender's own monkey head, mounted or resting as a bust among the objects — she may be the one \\\"portrait\\\" gazing out of the arrangement.\\n- A reflective checkered sphere — the ray-tracing demo classic — polished enough to catch the rest of the arrangement in its reflection.\\n- At least one supporting classical prop to sell the genre: fruit, a candlestick, an open book, a wine glass — pick what the composition needs.\\n\\nThe Cornell nod. Work the Cornell box palette into the scene's fabric: one strong red and one strong green element facing each other across the composition — draped cloths, wall panels, or book covers — with neutral white/grey between them, so the whole frame quietly becomes the box.\\n\\nMaterials & light. Chiaroscuro is the assignment: a single dominant warm light source (window shaft or candle) from one side, deep soft shadow elsewhere, a dark background that lets the objects emerge. Materials do the storytelling — glazed ceramic, patinated metal, velvet-dark cloth with real fold structure, polished chrome on the sphere. Everything slightly aged, nothing laboratory-clean.\\n\\nComposition. A table edge in the lower frame, objects grouped in overlapping depth with the teapot commanding the arrangement, camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent. The image should hold together as one calm, deliberate painting.\\n\\n</task>\"},{\"role\":\"assistant\",\"content\":\"Looking at this task, I need to create a Dutch Golden Age still life with CG history monuments: Utah Teapot, Stanford Bunny, Suzanne, a reflective checkered sphere, plus a classical prop, all lit with chiaroscuro and incorporating the Cornell box palette.\\n\\nLet me start by checking the current scene state and planning my approach.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-aadef2b898f113d4\",\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"arguments\":\"{}\"}},{\"id\":\"chatcmpl-tool-945d697d0850e4b7\",\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-aadef2b898f113d4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"datablock_counts\\\": {\\n      \\\"all_ids\\\": 35,\\n      \\\"cameras\\\": 1,\\n      \\\"collections\\\": 1,\\n      \\\"images\\\": 2,\\n      \\\"lights\\\": 1,\\n      \\\"linestyles\\\": 1,\\n      \\\"materials\\\": 2,\\n      \\\"meshes\\\": 1,\\n      \\\"palettes\\\": 1,\\n      \\\"scenes\\\": 1,\\n      \\\"screens\\\": 11,\\n      \\\"window_managers\\\": 1,\\n      \\\"workspaces\\\": 11,\\n      \\\"worlds\\\": 1\\n    },\\n    \\\"render_engine\\\": \\\"BLENDER_EEVEE\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"workspaces\\\": [\\n      \\\"Animation\\\",\\n      \\\"Compositing\\\",\\n      \\\"Geometry Nodes\\\",\\n      \\\"Layout\\\",\\n      \\\"Modeling\\\",\\n      \\\"Rendering\\\",\\n      \\\"Scripting\\\",\\n      \\\"Sculpting\\\",\\n      \\\"Shading\\\",\\n      \\\"Texture Paint\\\",\\n      \\\"UV Editing\\\"\\n    ],\\n    \\\"active_workspace\\\": \\\"Layout\\\"\\n  }\\n}\"},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-945d697d0850e4b7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"scene_name\\\": \\\"Scene\\\",\\n    \\\"active_workspace\\\": \\\"Layout\\\",\\n    \\\"active_object\\\": null,\\n    \\\"object_mode\\\": null,\\n    \\\"camera_object\\\": null,\\n    \\\"collections\\\": [\\n      {\\n        \\\"name\\\": \\\"Scene Collection\\\",\\n        \\\"exclude\\\": false,\\n        \\\"hide_viewport\\\": false,\\n        \\\"objects\\\": [],\\n        \\\"children\\\": [\\n          {\\n            \\\"name\\\": \\\"Collection\\\",\\n            \\\"exclude\\\": false,\\n            \\\"hide_viewport\\\": false,\\n            \\\"objects\\\": [],\\n            \\\"children\\\": []\\n          }\\n        ]\\n      }\\n    ]\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"The scene is essentially empty. Let me plan and build this Dutch Golden Age still life with CG history monuments. I'll work in stages: scene setup, environment (Cornell palette), then each hero object, lighting, camera, and materials.\\n\\nLet me start with the scene foundation — render settings, color management, and clearing defaults.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-be3274dc62602abe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# --- Clear the scene ---\\\\nbpy.ops.object.select_all(action='SELECT')\\\\nbpy.ops.object.delete(use_global=False, confirm=False)\\\\nfor block in list(bpy.data.meshes):\\\\n    bpy.data.meshes.remove(block)\\\\nfor block in list(bpy.data.materials):\\\\n    bpy.data.materials.remove(block)\\\\nfor block in list(bpy.data.curves):\\\\n    bpy.data.curves.remove(block)\\\\nfor block in list(bpy.data.lights):\\\\n    bpy.data.lights.remove(block)\\\\nfor block in list(bpy.data.cameras):\\\\n    bpy.data.cameras.remove(block)\\\\nfor block in list(bpy.data.images):\\\\n    bpy.data.images.remove(block)\\\\n\\\\n# --- Render settings: Cycles ---\\\\nscene = bpy.context.scene\\\\nscene.render.engine = 'CYCLES'\\\\nscene.cycles.device = 'GPU'\\\\nscene.cycles.samples = 128\\\\nscene.cycles.use_denoising = True\\\\nscene.render.resolution_x = 1536\\\\nscene.render.resolution_y = 1536\\\\nscene.render.resolution_percentage = 100\\\\nscene.render.film_transparent = False\\\\n\\\\n# Color management - filmic for painterly look\\\\nscene.view_settings.view_transform = 'Filmic'\\\\nscene.view_settings.look = 'Medium High Contrast'\\\\nscene.view_settings.exposure = 0.0\\\\n\\\\n# World - very dark ambient (chiaroscuro)\\\\nworld = scene.world\\\\nif world is None:\\\\n    world = bpy.data.worlds.new(\\\\\\\"World\\\\\\\")\\\\n    scene.world = world\\\\nworld.use_nodes = True\\\\nwn = world.node_tree\\\\nfor n in list(wn.nodes):\\\\n    wn.nodes.remove(n)\\\\nbg = wn.nodes.new('ShaderNodeBackground')\\\\nbg.inputs['Color'].default_value = (0.015, 0.012, 0.010, 1.0)\\\\nbg.inputs['Strength'].default_value = 0.3\\\\nout = wn.nodes.new('ShaderNodeOutputWorld')\\\\nwn.links.new(bg.outputs['Background'], out.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Scene foundation set up.\\\\\\\")\\\\nresult = {\\\\\\\"engine\\\\\\\": scene.render.engine, \\\\\\\"samples\\\\\\\": scene.cycles.samples, \\\\\\\"color_management\\\\\\\": scene.view_settings.view_transform}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-be3274dc62602abe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"engine\\\": \\\"CYCLES\\\",\\n    \\\"samples\\\": 128,\\n    \\\"color_management\\\": \\\"Filmic\\\"\\n  },\\n  \\\"stdout\\\": \\\"Scene foundation set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the environment — the Cornell-box-inspired backdrop with red and green panels, the table, and draped cloths.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix, Euler\\\\n\\\\ndef link_obj(obj, collection_name=None):\\\\n    if collection_name:\\\\n        coll = bpy.data.collections.get(collection_name)\\\\n        if coll is None:\\\\n            coll = bpy.data.collections.new(collection_name)\\\\n            bpy.context.scene.collection.children.link(coll)\\\\n        coll.objects.link(obj)\\\\n    else:\\\\n        bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# ENVIRONMENT: Cornell-box-inspired still life setting\\\\n# ============================================================\\\\n\\\\n# --- Back wall (neutral dark grey) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\nback_wall = bpy.context.active_object\\\\nback_wall.name = \\\\\\\"BackWall\\\\\\\"\\\\nback_wall.rotation_euler = (math.radians(90), 0, 0)\\\\nback_wall.location = (0, 2.5, 2.0)\\\\nback_wall.scale = (6, 4, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Subdivide for subtle variation\\\\nbpy.context.view_layer.objects.active = back_wall\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=20)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Red wall panel (left side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(-2.8, 1.8, 2.2))\\\\nred_panel = bpy.context.active_object\\\\nred_panel.name = \\\\\\\"RedPanel\\\\\\\"\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-15))\\\\nred_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Green wall panel (right side) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(2.8, 1.8, 2.2))\\\\ngreen_panel = bpy.context.active_object\\\\ngreen_panel.name = \\\\\\\"GreenPanel\\\\\\\"\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(15))\\\\ngreen_panel.scale = (2.5, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# --- Table top (aged wood) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, 0, 0))\\\\ntable = bpy.context.active_object\\\\ntable.name = \\\\\\\"TableTop\\\\\\\"\\\\ntable.scale = (6, 3.5, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Subdivide table for subtle surface variation\\\\nbpy.context.view_layer.objects.active = table\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=30)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\n# --- Table edge (front lip) ---\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, -1.75, -0.05))\\\\nedge = bpy.context.active_object\\\\nedge.name = \\\\\\\"TableEdge\\\\\\\"\\\\nedge.scale = (6, 0.1, 0.15)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# --- Floor (dark, extends to front) ---\\\\nbpy.ops.mesh.primitive_plane_add(size=1, location=(0, -3, -0.2))\\\\nfloor = bpy.context.active_object\\\\nfloor.name = \\\\\\\"Floor\\\\\\\"\\\\nfloor.scale = (12, 8, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\nprint(\\\\\\\"Environment geometry built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [o.name for o in bpy.data.objects]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-894c8e93bee6e8c2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"BackWall\\\",\\n      \\\"Floor\\\",\\n      \\\"GreenPanel\\\",\\n      \\\"RedPanel\\\",\\n      \\\"TableEdge\\\",\\n      \\\"TableTop\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Environment geometry built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the draped cloths with fold structure — red velvet on one side, green on the other.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a446a83c48a104cb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\nrandom.seed(42)\\\\n\\\\n# ============================================================\\\\n# DRAPED CLOTHS with fold structure\\\\n# ============================================================\\\\n\\\\ndef create_draped_cloth(name, location, rotation, scale, fold_intensity=0.08, fold_freq=8):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Create a draped cloth plane with fold-like displacement.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    bpy.ops.mesh.primitive_plane_add(size=1, location=location)\\\\n    obj = bpy.context.active_object\\\\n    obj.name = name\\\\n    obj.rotation_euler = rotation\\\\n    obj.scale = scale\\\\n    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n    \\\\n    # Subdivide heavily for folds\\\\n    bpy.context.view_layer.objects.active = obj\\\\n    bpy.ops.object.mode_set(mode='EDIT')\\\\n    bpy.ops.mesh.select_all(action='SELECT')\\\\n    bpy.ops.mesh.subdivide(number_cuts=40)\\\\n    bpy.ops.object.mode_set(mode='OBJECT')\\\\n    \\\\n    # Add folds via vertex displacement\\\\n    mesh = obj.data\\\\n    for v in mesh.vertices:\\\\n        x, y, z = v.co\\\\n        # Create fold-like ripples along the cloth\\\\n        fold_z = fold_intensity * (\\\\n            math.sin(x * fold_freq) * 0.5 +\\\\n            math.sin(x * fold_freq * 2.3 + 1.3) * 0.3 +\\\\n            math.cos(y * fold_freq * 0.7) * 0.2\\\\n        )\\\\n        # Dampen folds near attachment edge (top)\\\\n        edge_factor = min(1.0, abs(z) / 1.5)\\\\n        v.co.z += fold_z * edge_factor\\\\n    \\\\n    # Add solidify modifier for thickness\\\\n    mod = obj.modifiers.new(name=\\\\\\\"Solidify\\\\\\\", type='SOLIDIFY')\\\\n    mod.thickness = 0.015\\\\n    mod.offset = 0\\\\n    \\\\n    # Smooth shading\\\\n    bpy.ops.object.shade_smooth()\\\\n    \\\\n    return obj\\\\n\\\\n# --- Red velvet cloth (left side, draped from table edge) ---\\\\nred_cloth = create_draped_cloth(\\\\n    \\\\\\\"RedCloth\\\\\\\",\\\\n    location=(-2.2, -1.5, 0.02),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(3.5, 3.0, 1),\\\\n    fold_intensity=0.12,\\\\n    fold_freq=6\\\\n)\\\\n\\\\n# --- Green velvet cloth (right side, on table surface) ---\\\\ngreen_cloth = create_draped_cloth(\\\\n    \\\\\\\"GreenCloth\\\\\\\",\\\\n    location=(2.0, 0.3, 0.02),\\\\n    rotation=(0, 0, math.radians(8)),\\\\n    scale=(3.0, 2.8, 1),\\\\n    fold_intensity=0.08,\\\\n    fold_freq=7\\\\n)\\\\n\\\\n# --- White/grey linen runner (center, between red and green - Cornell neutral) ---\\\\nwhite_cloth = create_draped_cloth(\\\\n    \\\\\\\"WhiteCloth\\\\\\\",\\\\n    location=(0.0, -0.2, 0.03),\\\\n    rotation=(0, 0, 0),\\\\n    scale=(2.5, 2.2, 1),\\\\n    fold_intensity=0.04,\\\\n    fold_freq=10\\\\n)\\\\n\\\\nprint(\\\\\\\"Draped cloths built.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_objects\\\\\\\": [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\", \\\\\\\"WhiteCloth\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a446a83c48a104cb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_objects\\\": [\\n      \\\"RedCloth\\\",\\n      \\\"GreenCloth\\\",\\n      \\\"WhiteCloth\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Draped cloths built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the hero object — the Utah Teapot. I'll construct it from its component parts (body, spout, handle, lid) using Bezier curves and revolves.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# THE UTAH TEAPOT — the hero\\\\n# Classic squat proportions, built from profile curves revolved\\\\n# ============================================================\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# --- Teapot Body: lathe a profile ---\\\\n# Profile points (radius, height) tracing the classic teapot body silhouette\\\\nbody_profile = [\\\\n    (0.00, 0.00),   # center bottom\\\\n    (0.35, 0.00),   # base edge\\\\n    (0.55, 0.02),   # \\\\n    (0.70, 0.08),   # bulge start\\\\n    (0.82, 0.20),   # widest bulge lower\\\\n    (0.88, 0.35),   # widest point\\\\n    (0.87, 0.50),   # \\\\n    (0.80, 0.65),   # tapering up\\\\n    (0.70, 0.78),   # \\\\n    (0.55, 0.88),   # shoulder\\\\n    (0.40, 0.94),   # neck\\\\n    (0.32, 0.98),   # lid seat\\\\n    (0.30, 1.00),   # top opening edge\\\\n]\\\\n\\\\n# Build the body as a lathed mesh\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotBodyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 48\\\\n# Create rings of vertices\\\\nall_verts = []\\\\nfor r, h in body_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        # single vertex at center (pole)\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Create faces between rings\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = body_profile[ri]\\\\n    rb, _ = body_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            # triangle fan\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbody_obj = bpy.data.objects.new(\\\\\\\"TeapotBody\\\\\\\", mesh)\\\\nlink_obj(body_obj)\\\\nbpy.context.view_layer.objects.active = body_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subdivision surface for smoothness\\\\nmod = body_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\nprint(\\\\\\\"Teapot body built.\\\\\\\")\\\\nresult = {\\\\\\\"verts\\\\\\\": len(mesh.vertices), \\\\\\\"faces\\\\\\\": len(mesh.polygons)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f91ff705ec7e347\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"verts\\\": 577,\\n    \\\"faces\\\": 576\\n  },\\n  \\\"stdout\\\": \\\"Teapot body built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the teapot spout, handle, and lid.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT SPOUT — curved tube\\\\n# ============================================================\\\\n# The spout rises from the lower body, curves outward and up\\\\n\\\\nspout_curve_data = bpy.data.curves.new('TeapotSpoutCurve', type='CURVE')\\\\nspout_curve_data.dimensions = '3D'\\\\nspout_curve_data.resolution_u = 16\\\\nspout_curve_data.bevel_depth = 0.0  # we'll build mesh manually\\\\n\\\\nspline = spout_curve_data.splines.new('BEZIER')\\\\n# Control points tracing the spout path (in body-local space)\\\\n# Spout exits body around (0.85, 0, 0.25), curves up and out\\\\nspout_points = [\\\\n    (0.82, 0, 0.22),   # base at body\\\\n    (1.05, 0, 0.30),   # curving out\\\\n    (1.25, 0, 0.45),   # mid\\\\n    (1.38, 0, 0.62),   # curving up\\\\n    (1.42, 0, 0.80),   # near tip\\\\n    (1.40, 0, 0.92),   # tip\\\\n]\\\\nspline.bezier_points.add(len(spout_points) - 1)\\\\nfor i, pt in enumerate(spout_points):\\\\n    bp = spline.bezier_points[i]\\\\n    bp.co = pt\\\\n    bp.handle_left_type = 'AUTO'\\\\n    bp.handle_right_type = 'AUTO'\\\\n\\\\nspout_obj = bpy.data.objects.new('TeapotSpout', spout_curve_data)\\\\nlink_obj(spout_obj)\\\\n\\\\n# Convert curve to mesh, then taper it\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.select_all(action='DESELECT')\\\\nspout_obj.select_set(True)\\\\nbpy.ops.object.convert(target='MESH')\\\\n\\\\nspout_mesh = spout_obj.data\\\\n# Taper the spout: make it wider at base, narrower at tip\\\\n# The mesh from curve conversion has vertices along the path\\\\n# We'll scale based on z height\\\\nmin_z = min(v.co.z for v in spout_mesh.vertices)\\\\nmax_z = max(v.co.z for v in spout_mesh.vertices)\\\\nz_range = max_z - min_z\\\\n\\\\nfor v in spout_mesh.vertices:\\\\n    # normalize position along path (0=base, 1=tip)\\\\n    t = (v.co.z - min_z) / max(z_range, 0.001)\\\\n    # Radius taper: thick at base, narrow at tip\\\\n    # Also widen the opening at the very tip (lip)\\\\n    if t > 0.85:\\\\n        # flare slightly at the spout lip\\\\n        radius_factor = 0.12 + (t - 0.85) * 0.5\\\\n    else:\\\\n        radius_factor = 0.18 - t * 0.06\\\\n    # Scale x,y around the path center (approximate by scaling from local axis)\\\\n    # The spout extends along +x, so scale y and z-offset\\\\n    center_x = 1.1  # approximate path center\\\\n    v.co.y *= (radius_factor / 0.18)\\\\n    v.co.z = v.co.z  # keep z\\\\n\\\\n# Actually, let me rebuild the spout more carefully with a proper tube\\\\nbpy.data.objects.remove(spout_obj, do_unlink=True)\\\\n\\\\n# --- Rebuild spout as a proper tapered tube ---\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotSpoutMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Spout centerline points\\\\npath_points = [\\\\n    Vector((0.80, 0, 0.20)),\\\\n    Vector((1.00, 0, 0.26)),\\\\n    Vector((1.20, 0, 0.38)),\\\\n    Vector((1.34, 0, 0.55)),\\\\n    Vector((1.40, 0, 0.74)),\\\\n    Vector((1.38, 0, 0.90)),\\\\n]\\\\n# Radii at each point\\\\npath_radii = [0.16, 0.14, 0.12, 0.10, 0.09, 0.11]  # slight flare at tip\\\\n\\\\n# Generate rings\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    # Compute tangent (direction along path)\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    # Build a frame perpendicular to tangent\\\\n    # Spout goes roughly in +x and +z, so normal plane spans y and (perp in xz)\\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\n# Connect rings with faces\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\n# Cap the tip (top) - the spout opening\\\\ntip_ring = rings[-1]\\\\ncenter = sum((v.co for v in tip_ring), Vector()) / len(tip_ring)\\\\n# Don't cap - leave open as a spout opening, but add a slight rim\\\\n# Actually cap the base where it meets the body\\\\nbase_ring = rings[0]\\\\nbase_center = sum((v.co for v in base_ring), Vector()) / len(base_ring)\\\\n# Leave both open for now (base merges into body)\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nspout_obj = bpy.data.objects.new(\\\\\\\"TeapotSpout\\\\\\\", mesh)\\\\nlink_obj(spout_obj)\\\\nbpy.context.view_layer.objects.active = spout_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = spout_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Teapot spout built.\\\\\\\")\\\\nresult = {\\\\\\\"spout_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8655fd34dc5d3d15\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"spout_verts\\\": 144\\n  },\\n  \\\"stdout\\\": \\\"Teapot spout built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# TEAPOT HANDLE — curved handle on the opposite side from spout\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotHandleMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\nsegments = 24\\\\n# Handle path: starts on body upper-left, curves down and around to body lower-left\\\\n# Handle is on the -x side (opposite the spout)\\\\npath_points = [\\\\n    Vector((-0.78, 0, 0.72)),   # top attachment\\\\n    Vector((-1.05, 0, 0.68)),   # upper curve out\\\\n    Vector((-1.18, 0, 0.55)),   # outer\\\\n    Vector((-1.15, 0, 0.38)),   # mid\\\\n    Vector((-1.05, 0, 0.22)),   # lower curve in\\\\n    Vector((-0.82, 0, 0.18)),   # bottom attachment\\\\n]\\\\npath_radii = [0.07, 0.08, 0.085, 0.085, 0.08, 0.07]\\\\n\\\\nrings = []\\\\nfor pi, (p, r) in enumerate(zip(path_points, path_radii)):\\\\n    ring = []\\\\n    if pi == 0:\\\\n        tangent = (path_points[1] - path_points[0]).normalized()\\\\n    elif pi == len(path_points) - 1:\\\\n        tangent = (path_points[-1] - path_points[-2]).normalized()\\\\n    else:\\\\n        tangent = (path_points[pi+1] - path_points[pi-1]).normalized()\\\\n    \\\\n    up = Vector((0, 0, 1))\\\\n    if abs(tangent.dot(up)) > 0.9:\\\\n        up = Vector((1, 0, 0))\\\\n    right = tangent.cross(up).normalized()\\\\n    up = right.cross(tangent).normalized()\\\\n    \\\\n    for i in range(segments):\\\\n        angle = (i / segments) * math.tau\\\\n        offset = (math.cos(angle) * right + math.sin(angle) * up) * r\\\\n        v = bm.verts.new(p + offset)\\\\n        ring.append(v)\\\\n    rings.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(rings) - 1):\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        bm.faces.new([rings[ri][i], rings[ri+1][i], rings[ri+1][j], rings[ri][j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nhandle_obj = bpy.data.objects.new(\\\\\\\"TeapotHandle\\\\\\\", mesh)\\\\nlink_obj(handle_obj)\\\\nbpy.context.view_layer.objects.active = handle_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = handle_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# ============================================================\\\\n# TEAPOT LID — dome with knob\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"TeapotLidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Lid profile: sits on the neck, domes up, has a knob\\\\nlid_profile = [\\\\n    (0.00, 0.98),   # center\\\\n    (0.30, 0.98),   # seat edge (matches neck top)\\\\n    (0.30, 1.00),   # lip up\\\\n    (0.28, 1.02),   # \\\\n    (0.24, 1.06),   # dome\\\\n    (0.18, 1.10),   # \\\\n    (0.12, 1.13),   # \\\\n    (0.07, 1.15),   # knob base\\\\n    (0.05, 1.17),   # \\\\n    (0.04, 1.19),   # knob top\\\\n    (0.00, 1.19),   # knob cap\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in lid_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = lid_profile[ri]\\\\n    rb, _ = lid_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nlid_obj = bpy.data.objects.new(\\\\\\\"TeapotLid\\\\\\\", mesh)\\\\nlink_obj(lid_obj)\\\\nbpy.context.view_layer.objects.active = lid_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = lid_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 2\\\\nmod.render_levels = 3\\\\n\\\\n# Parent all teapot parts to an empty for easy positioning\\\\nbpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))\\\\nteapot_empty = bpy.context.active_object\\\\nteapot_empty.name = \\\\\\\"UtahTeapot\\\\\\\"\\\\nteapot_empty.empty_display_size = 0.5\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.parent = teapot_empty\\\\n    obj.matrix_parent_inverse = teapot_empty.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Teapot handle, lid built and parented.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_parts\\\\\\\": [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bc4ec4ddd3e82626\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_parts\\\": [\\n      \\\"TeapotBody\\\",\\n      \\\"TeapotSpout\\\",\\n      \\\"TeapotHandle\\\",\\n      \\\"TeapotLid\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Teapot handle, lid built and parented.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build the Stanford Bunny — a sculptural approximation with the compact crouched silhouette.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# STANFORD BUNNY — compact crouched-rabbit silhouette\\\\n# Built from metaballs / shaped spheres for the rounded organic form\\\\n# ============================================================\\\\n\\\\n# Use a base mesh and shape it with proportional editing-like vertex math\\\\n# Start with a UV sphere and sculpt the bunny form\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"BunnyMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create the bunny body as a series of merged spheres\\\\n# This is a sculptural approximation - crouched rabbit, rounded back, folded ears\\\\n\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, segments=48, ring_count=24, location=(0,0,0))\\\\nbody = bpy.context.active_object\\\\nbody.name = \\\\\\\"BunnyBodyTemp\\\\\\\"\\\\n\\\\n# We'll build the bunny from multiple metaball-like sphere parts merged\\\\n# Body parts (in local space, will be positioned later):\\\\nparts = []\\\\n\\\\ndef add_sphere_part(bm, center, radius, segments=32, rings=16, squash=(1,1,1)):\\\\n    \\\\\\\"\\\\\\\"\\\\\\\"Add a sphere of vertices to bmesh, returns the ring structure.\\\\\\\"\\\\\\\"\\\\\\\"\\\\n    verts_grid = []\\\\n    for ri in range(rings + 1):\\\\n        phi = math.pi * ri / rings  # 0 to pi\\\\n        ring = []\\\\n        for si in range(segments):\\\\n            theta = math.tau * si / segments\\\\n            x = radius * math.sin(phi) * math.cos(theta) * squash[0]\\\\n            y = radius * math.sin(phi) * math.sin(theta) * squash[1]\\\\n            z = radius * math.cos(phi) * squash[2]\\\\n            v = bm.verts.new((center[0] + x, center[1] + y, center[2] + z))\\\\n            ring.append(v)\\\\n        verts_grid.append(ring)\\\\n    \\\\n    # Create faces\\\\n    for ri in range(rings):\\\\n        for si in range(segments):\\\\n            sj = (si + 1) % segments\\\\n            try:\\\\n                bm.faces.new([verts_grid[ri][si], verts_grid[ri+1][si], verts_grid[ri+1][sj], verts_grid[ri][sj]])\\\\n            except:\\\\n                pass\\\\n    return verts_grid\\\\n\\\\n# Delete temp object\\\\nbpy.data.objects.remove(body, do_unlink=True)\\\\n\\\\n# Build bunny as a union of squashed spheres\\\\n# The Stanford bunny sits crouched, facing forward, with a rounded back\\\\n# Key features: rounded body mass, head tucked forward, folded ears along back\\\\n\\\\n# Main body mass (large, elongated, crouched)\\\\nadd_sphere_part(bm, (0, 0, 0.18), 0.28, segments=48, rings=24, squash=(1.4, 0.9, 0.85))\\\\n# Lower body / haunches\\\\nadd_sphere_part(bm, (0, 0, 0.05), 0.22, segments=48, rings=24, squash=(1.3, 0.95, 0.6))\\\\n# Head (forward and slightly down)\\\\nadd_sphere_part(bm, (0.32, 0, 0.28), 0.16, segments=48, rings=24, squash=(1.1, 0.9, 0.95))\\\\n# Nose area\\\\nadd_sphere_part(bm, (0.44, 0, 0.24), 0.07, segments=32, rings=16, squash=(1.0, 0.8, 0.8))\\\\n\\\\n# Ears (folded back along the body) - two flattened elongated forms\\\\n# Left ear\\\\nadd_sphere_part(bm, (0.05, 0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n# Right ear\\\\nadd_sphere_part(bm, (0.05, -0.10, 0.46), 0.10, segments=48, rings=24, squash=(0.35, 0.25, 1.6))\\\\n\\\\n# Front legs/paws (folded under)\\\\nadd_sphere_part(bm, (0.25, 0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\nadd_sphere_part(bm, (0.25, -0.05, 0.0), 0.08, segments=32, rings=16, squash=(1.2, 0.6, 0.4))\\\\n\\\\n# Back haunches (raised)\\\\nadd_sphere_part(bm, (-0.15, 0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\nadd_sphere_part(bm, (-0.15, -0.12, 0.12), 0.14, segments=48, rings=24, squash=(1.0, 0.8, 1.1))\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nbunny_obj = bpy.data.objects.new(\\\\\\\"StanfordBunny\\\\\\\", mesh)\\\\nlink_obj(bunny_obj)\\\\nbpy.context.view_layer.objects.active = bunny_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add remesh modifier to unify the separate spheres into a smooth surface\\\\n# Use a remesh to blend the parts\\\\nremesh = bunny_obj.modifiers.new(\\\\\\\"Remesh\\\\\\\", 'REMESH')\\\\nremesh.mode = 'SMOOTH'\\\\nremesh.voxel_size = 0.03\\\\nremesh.adaptivity = 0.002\\\\n\\\\n# Add subsurf after remesh for extra smoothness\\\\nsubsurf = bunny_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nsubsurf.levels = 1\\\\nsubsurf.render_levels = 2\\\\n\\\\n# Scale to sit on table at reasonable size\\\\nbunny_obj.scale = (1.0, 1.0, 1.0)\\\\n\\\\nprint(\\\\\\\"Stanford Bunny built.\\\\\\\")\\\\nresult = {\\\\\\\"bunny_verts\\\\\\\": len(mesh.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9d958d1dbd0f2bc4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"bunny_verts\\\": 10032\\n  },\\n  \\\"stdout\\\": \\\"Stanford Bunny built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me build Suzanne (Blender's monkey head) as a bust, and the checkered sphere.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b30242086301c8e0\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\n# ============================================================\\\\n# SUZANNE — Blender's monkey head, as a bust\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_monkey_add(size=0.5, location=(0, 0, 0))\\\\nsuzanne = bpy.context.active_object\\\\nsuzanne.name = \\\\\\\"Suzanne\\\\\\\"\\\\n\\\\n# Add a simple bust base/pedestal under Suzanne\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.12, depth=0.15, location=(0, 0, -0.15))\\\\nbust_base = bpy.context.active_object\\\\nbust_base.name = \\\\\\\"SuzanneBase\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Taper the base slightly (classical bust pedestal)\\\\nbpy.context.view_layer.objects.active = bust_base\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=3)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n# Scale top vertices slightly\\\\nmesh = bust_base.data\\\\nfor v in mesh.vertices:\\\\n    if v.co.z > 0.04:\\\\n        v.co.x *= 0.7\\\\n        v.co.y *= 0.7\\\\n\\\\n# Parent base to Suzanne for now\\\\nbust_base.parent = suzanne\\\\nbust_base.matrix_parent_inverse = suzanne.matrix_world.inverted()\\\\n\\\\nprint(\\\\\\\"Suzanne and bust base built.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# CHECKERED SPHERE — ray-tracing demo classic\\\\n# ============================================================\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.22, segments=64, ring_count=32, location=(0, 0, 0))\\\\nsphere = bpy.context.active_object\\\\nsphere.name = \\\\\\\"CheckeredSphere\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add subsurf for perfectly smooth sphere\\\\nmod = sphere.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\nprint(\\\\\\\"Checkered sphere built.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_verts\\\\\\\": len(suzanne.data.vertices), \\\\\\\"sphere_verts\\\\\\\": len(sphere.data.vertices)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b30242086301c8e0\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_verts\\\": 507,\\n    \\\"sphere_verts\\\": 1986\\n  },\\n  \\\"stdout\\\": \\\"Suzanne and bust base built.\\\\nCheckered sphere built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me add the supporting classical props — I'll create a wine glass, a book, and some fruit.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b3944ff151600684\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector, Matrix\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# WINE GLASS — classical still life prop\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineGlassMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the wine glass (radius, height) — lathed\\\\nglass_profile = [\\\\n    (0.00, 0.00),    # base center\\\\n    (0.14, 0.00),    # base edge\\\\n    (0.15, 0.01),    # base lip\\\\n    (0.13, 0.02),    # \\\\n    (0.04, 0.03),    # stem base\\\\n    (0.035, 0.10),   # stem\\\\n    (0.035, 0.18),   # stem\\\\n    (0.04, 0.25),    # bowl base\\\\n    (0.08, 0.30),    # bowl widening\\\\n    (0.12, 0.36),    # \\\\n    (0.14, 0.42),    # bowl widest\\\\n    (0.135, 0.48),   # \\\\n    (0.11, 0.53),    # tapering in\\\\n    (0.08, 0.57),    # \\\\n    (0.06, 0.60),    # rim\\\\n    (0.00, 0.60),    # center top (open)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in glass_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = glass_profile[ri]\\\\n    rb, _ = glass_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Don't cap the top - leave open\\\\n            pass\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nglass_obj = bpy.data.objects.new(\\\\\\\"WineGlass\\\\\\\", mesh)\\\\nlink_obj(glass_obj)\\\\nbpy.context.view_layer.objects.active = glass_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify for glass thickness\\\\nmod = glass_obj.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.004\\\\nmod.offset = 1\\\\n\\\\n# ============================================================\\\\n# OPEN BOOK — classical still life prop\\\\n# ============================================================\\\\n# Book base (two pages meeting at spine)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))\\\\nbook = bpy.context.active_object\\\\nbook.name = \\\\\\\"OpenBook\\\\\\\"\\\\nbook.scale = (0.45, 0.32, 0.03)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape the pages - create a V-shape for open book\\\\nbpy.context.view_layer.objects.active = book\\\\nbpy.ops.object.mode_set(mode='EDIT')\\\\nbpy.ops.mesh.select_all(action='SELECT')\\\\nbpy.ops.mesh.subdivide(number_cuts=8)\\\\nbpy.ops.object.mode_set(mode='OBJECT')\\\\n\\\\nmesh = book.data\\\\n# Create the V-shape: spine in center dips down, edges curve up slightly\\\\nfor v in mesh.vertices:\\\\n    # Distance from center line (x=0 is spine)\\\\n    dist_from_spine = abs(v.co.x)\\\\n    # Pages curve up at edges\\\\n    v.co.z += 0.02 * (dist_from_spine / 0.45) ** 1.5\\\\n    # Spine dips\\\\n    if dist_from_spine < 0.05:\\\\n        v.co.z -= 0.01\\\\n\\\\n# Add a second thin cube for the cover (darker)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.02))\\\\ncover = bpy.context.active_object\\\\ncover.name = \\\\\\\"BookCover\\\\\\\"\\\\ncover.scale = (0.48, 0.34, 0.015)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Shape cover to match\\\\nmesh = cover.data\\\\nfor v in mesh.vertices:\\\\n    dist_from_spine = abs(v.co.x)\\\\n    v.co.z += 0.022 * (dist_from_spine / 0.48) ** 1.5\\\\n\\\\n# ============================================================\\\\n# FRUIT — a few oranges/lemons for color and life\\\\n# ============================================================\\\\nfruits = []\\\\nfruit_colors = [\\\\n    ((0.10, 0, 0), 0.09, \\\\\\\"Orange1\\\\\\\"),   # orange, slight offset\\\\n    ((0.18, 0.08, 0), 0.075, \\\\\\\"Orange2\\\\\\\"),  # orange, different position\\\\n    ((0.0, 0.12, 0), 0.08, \\\\\\\"Lemon1\\\\\\\"),   # lemon\\\\n]\\\\n\\\\nfor i, (pos, radius, name) in enumerate(fruit_colors):\\\\n    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, segments=32, ring_count=16, location=pos)\\\\n    fruit = bpy.context.active_object\\\\n    fruit.name = name\\\\n    # Squash slightly for fruit shape\\\\n    fruit.scale = (1.0, 1.0, 0.88)\\\\n    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n    bpy.ops.object.shade_smooth()\\\\n    fruits.append(fruit)\\\\n\\\\nprint(\\\\\\\"Wine glass, book, and fruit built.\\\\\\\")\\\\nresult = {\\\\\\\"objects\\\\\\\": [\\\\\\\"WineGlass\\\\\\\", \\\\\\\"OpenBook\\\\\\\", \\\\\\\"BookCover\\\\\\\"] + [f.name for f in fruits]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b3944ff151600684\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"objects\\\": [\\n      \\\"WineGlass\\\",\\n      \\\"OpenBook\\\",\\n      \\\"BookCover\\\",\\n      \\\"Orange1\\\",\\n      \\\"Orange2\\\",\\n      \\\"Lemon1\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Wine glass, book, and fruit built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me position all the objects in the composition, then create materials. Let me arrange everything on the table.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a11b11ab0c461694\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# COMPOSITION: Position all objects on the table\\\\n# Camera will be at slightly-elevated angle, ~50mm equivalent\\\\n# Teapot commands the arrangement (center-hero), others grouped around\\\\n# ============================================================\\\\n\\\\n# Table surface is at z=0\\\\n# Camera will look from front-left, slightly elevated\\\\n\\\\n# --- Utah Teapot (hero, center, commanding) ---\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (-0.1, 0.1, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-25))\\\\nteapot.scale = (0.85, 0.85, 0.85)\\\\n\\\\n# --- Stanford Bunny (left of teapot, on green cloth area) ---\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.15, 0.25, 0.03)\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\nbunny.scale = (1.3, 1.3, 1.3)\\\\n\\\\n# --- Suzanne (right of teapot, as bust portrait gazing out) ---\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.05, 0.18)\\\\nsuzanne.rotation_euler = (math.radians(15), math.radians(-10), math.radians(70))\\\\n\\\\n# --- Checkered Sphere (front-center, in front of teapot) ---\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.15, -0.55, 0.22)\\\\n\\\\n# --- Wine Glass (right side, back) ---\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.55, 0.3, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\n# --- Open Book (left-front, partially under bunny) ---\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.6, -0.7, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(15))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location\\\\ncover.rotation_euler = book.rotation_euler\\\\n\\\\n# --- Fruit (clustered near front-right) ---\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.85, -0.75, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.05, -0.65, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, 0)\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.7, -0.55, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(45))\\\\n\\\\nprint(\\\\\\\"All objects positioned.\\\\\\\")\\\\nresult = {o.name: list(o.location) for o in bpy.data.objects if o.type == 'MESH' or o.name == 'UtahTeapot'}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a11b11ab0c461694\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"BackWall\\\": [\\n      0.0,\\n      2.5,\\n      2.0\\n    ],\\n    \\\"BookCover\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"CheckeredSphere\\\": [\\n      0.15000000596046448,\\n      -0.550000011920929,\\n      0.2199999988079071\\n    ],\\n    \\\"Floor\\\": [\\n      0.0,\\n      -3.0,\\n      -0.20000000298023224\\n    ],\\n    \\\"GreenCloth\\\": [\\n      2.0,\\n      0.30000001192092896,\\n      0.019999999552965164\\n    ],\\n    \\\"GreenPanel\\\": [\\n      2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"Lemon1\\\": [\\n      0.699999988079071,\\n      -0.550000011920929,\\n      0.07999999821186066\\n    ],\\n    \\\"OpenBook\\\": [\\n      -0.6000000238418579,\\n      -0.699999988079071,\\n      0.019999999552965164\\n    ],\\n    \\\"Orange1\\\": [\\n      0.8500000238418579,\\n      -0.75,\\n      0.09000000357627869\\n    ],\\n    \\\"Orange2\\\": [\\n      1.0499999523162842,\\n      -0.6499999761581421,\\n      0.07500000298023224\\n    ],\\n    \\\"RedCloth\\\": [\\n      -2.200000047683716,\\n      -1.5,\\n      0.019999999552965164\\n    ],\\n    \\\"RedPanel\\\": [\\n      -2.799999952316284,\\n      1.7999999523162842,\\n      2.200000047683716\\n    ],\\n    \\\"StanfordBunny\\\": [\\n      -1.149999976158142,\\n      0.25,\\n      0.029999999329447746\\n    ],\\n    \\\"Suzanne\\\": [\\n      1.0,\\n      -0.05000000074505806,\\n      0.18000000715255737\\n    ],\\n    \\\"SuzanneBase\\\": [\\n      0.0,\\n      0.0,\\n      -0.15000000596046448\\n    ],\\n    \\\"TableEdge\\\": [\\n      0.0,\\n      -1.75,\\n      -0.05000000074505806\\n    ],\\n    \\\"TableTop\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotBody\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotHandle\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotLid\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"TeapotSpout\\\": [\\n      0.0,\\n      0.0,\\n      0.0\\n    ],\\n    \\\"UtahTeapot\\\": [\\n      -0.10000000149011612,\\n      0.10000000149011612,\\n      0.0\\n    ],\\n    \\\"WhiteCloth\\\": [\\n      0.0,\\n      -0.20000000298023224,\\n      0.029999999329447746\\n    ],\\n    \\\"WineGlass\\\": [\\n      1.5499999523162842,\\n      0.30000001192092896,\\n      0.0\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"All objects positioned.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me create all the materials. This is where the storytelling happens — aged ceramic, patinated metal, velvet cloth, polished chrome.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# MATERIALS\\\\n# ============================================================\\\\n\\\\n# --- 1. TEAPOT: Glazed ceramic with silver accents (Vermeer-worthy) ---\\\\nmat, nt = create_material(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.72, 0.68, 0.60, 1.0)  # warm cream\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n# Add subtle noise for ceramic imperfection\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, -100))\\\\nnoise.inputs['Scale'].default_value = 35.0\\\\nnoise.inputs['Detail'].default_value = 8.0\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.15\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n# Color variation\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (-200, 100))\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise2.inputs['Scale'].default_value = 8.0\\\\nnoise2.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise2.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.66, 0.58, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.76, 0.72, 0.64, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    if obj.data.materials:\\\\n        obj.data.materials[0] = mat\\\\n    else:\\\\n        obj.data.materials.append(mat)\\\\n\\\\n# --- 2. STANFORD BUNNY: Bronze/patinated sculpture material ---\\\\nmat, nt = create_material(\\\\\\\"M_BunnyBronze\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation (greenish patches)\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 100))\\\\nnoise.inputs['Scale'].default_value = 4.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.40, 0.25, 1.0)  # bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.38, 0.28, 1.0)  # patina green\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Roughness variation\\\\nnt.links.new(noise.outputs['Fac'], bsdf.inputs['Roughness'])\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 50.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nif bunny.data.materials:\\\\n    bunny.data.materials[0] = mat\\\\nelse:\\\\n    bunny.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Teapot and bunny materials created.\\\\\\\")\\\\nresult = {\\\\\\\"teapot_mat\\\\\\\": \\\\\\\"M_TeapotCeramic\\\\\\\", \\\\\\\"bunny_mat\\\\\\\": \\\\\\\"M_BunnyBronze\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-971ae09b09cd7c7d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"teapot_mat\\\": \\\"M_TeapotCeramic\\\",\\n    \\\"bunny_mat\\\": \\\"M_BunnyBronze\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot and bunny materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 3. SUZANNE: Marble bust material ---\\\\nmat, nt = create_material(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.83, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.3\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-400, 100))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnoise.inputs['Distortion'].default_value = 1.5\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-600, 100))\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nmix = add_node(nt, 'ShaderNodeMix', (-200, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[2])  # A\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[3])  # B\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 100))\\\\nnt.links.new(mix.outputs[2], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.82, 0.80, 0.75, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.5, 0.42, 0.38, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (0, -100))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = historyMat\\\\nelse:\\\\n    suzanne.data.materials.append(mat)\\\\n\\\\n# Bust base - darker marble\\\\nmat_base, nt = create_material(\\\\\\\"M_BustBase\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.3, 0.27, 0.23, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.4\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nif base.data.materials:\\\\n    base.data.materials[0] = mat_base\\\\nelse:\\\\n    base.data.materials.append(mat_base)\\\\n\\\\n# --- 4. CHECKERED SPHERE: Polished chrome with checker pattern ---\\\\nmat, nt = create_material(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished\\\\n\\\\n# Checker pattern\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 12.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.05, 0.05, 0.05, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nif sphere.data.materials:\\\\n    sphere.data.materials[0] = mat\\\\nelse:\\\\n    sphere.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Suzanne, bust base, and checkered sphere materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a5082ce8c009bea7\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne, bust base, and checkered sphere materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see a bug — I referenced `historyMat` instead of `mat` for Suzanne. Let me fix that and continue with the cloth and environment materials.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b99d874b987317e9\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix Suzanne material assignment\\\\nmat_suzanne = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nif suzanne.data.materials:\\\\n    suzanne.data.materials[0] = mat_suzanne\\\\nelse:\\\\n    suzanne.data.materials.append(mat_suzanne)\\\\n\\\\nprint(\\\\\\\"Fixed Suzanne material.\\\\\\\")\\\\nresult = {\\\\\\\"suzanne_materials\\\\\\\": [m.name for m in suzanne.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b99d874b987317e9\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"suzanne_materials\\\": [\\n      \\\"M_SuzanneMarble\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Fixed Suzanne material.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)  # deep Cornell red\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\n# Velvet sheen via noise\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Cloth bump for weave\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)  # deep Cornell green\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Rec'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN (neutral Cornell element) ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)  # warm grey-white\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a837f3bf886e2bf3\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 58, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Rec\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me fix that typo — I used `Rec` instead of `Fac`.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 5. RED VELVET CLOTH (Cornell red) ---\\\\nmat, nt = create_material(\\\\\\\"M_RedVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.45, 0.05, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.40, 0.04, 0.03, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.55, 0.08, 0.06, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"RedCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 6. GREEN VELVET CLOTH (Cornell green) ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenVelvet\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.05, 0.30, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 15.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])  # Fixed: 'Fac' not 'Rec'\\\\ncolor_ramp.color_ramp.elements[0].color = (0.04, 0.28, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.08, 0.35, 0.08, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 120.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 7. WHITE/GREY LINEN ---\\\\nmat, nt = create_material(\\\\\\\"M_WhiteLinen\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.73, 0.68, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.3\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 20.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.70, 0.68, 0.63, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.80, 0.78, 0.73, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 150.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Cloth materials created.\\\\\\\")\\\\nresult = {\\\\\\\"cloth_materials\\\\\\\": [\\\\\\\"M_RedVelvet\\\\\\\", \\\\\\\"M_GreenVelvet\\\\\\\", \\\\\\\"M_WhiteLinen\\\\\\\"]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-85fb82aff4f7bc91\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"cloth_materials\\\": [\\n      \\\"M_RedVelvet\\\",\\n      \\\"M_GreenVelvet\\\",\\n      \\\"M_WhiteLinen\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Cloth materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now the environment and remaining prop materials — walls, table, fruit, glass, book.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL (dark, aged plaster) ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP (aged wood) ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\n# Wood grain\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Table edge and floor share table material\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b552d51ab059a6e8\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 59\\\\n    nt.links.new(bsdf objs['BSDF'], output.inputs['Surface'])\\\\n                 ^^^^^^^^^^^^^^^^^\\\\nSyntaxError: invalid syntax. Perhaps you forgot a comma?\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 8. BACK WALL ---\\\\nmat, nt = create_material(\\\\\\\"M_BackWall\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.10, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 8.0\\\\nnoise.inputs['Detail'].default_value = 6.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.10, 0.08, 0.06, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.16, 0.13, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.3\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 30.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"BackWall\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 9. RED PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_RedPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.04, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"RedPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 10. GREEN PANEL ---\\\\nmat, nt = create_material(\\\\\\\"M_GreenPanel\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.04, 0.22, 0.05, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 11. TABLE TOP ---\\\\nmat, nt = create_material(\\\\\\\"M_TableTop\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.20, 0.14, 0.08, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.6\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (0, 100))\\\\nwave.wave_type = 'BANDS'\\\\nwave.inputs['Scale'].default_value = 2.0\\\\nwave.inputs['Distortion'].default_value = 8.0\\\\nwave.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(wave.outputs['Color'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.15, 0.10, 0.05, 1.0)\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.18, 0.10, 1.0)\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnt.links.new(wave.outputs['Color'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"TableTop\\\\\\\"].data.materials.append(mat)\\\\nbpy.data.objects[\\\\\\\"TableEdge\\\\\\\"].data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 12. FLOOR ---\\\\nmat, nt = create_material(\\\\\\\"M_Floor\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.08, 0.06, 0.04, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.9\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Floor\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Environment materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7c6aebd182a662\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Environment materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a15057346df8e108\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- 13. WINE GLASS (glass with wine) ---\\\\nmat, nt = create_material(\\\\\\\"M_WineGlass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nglass = add_node(nt, 'ShaderNodeBsdfGlass', (300, 0))\\\\nglass.inputs['Color'].default_value = (0.95, 0.98, 0.95, 1.0)\\\\nglass.inputs['Roughness'].default_value = 0.0\\\\nglass.inputs['IOR'].default_value = 1.45\\\\nnt.links.new(glass.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 14. BOOK PAGES (aged paper) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookPages\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.74, 0.58, 1.0)  # aged paper\\\\nbsdf.inputs['Roughness'].default_value = 0.85\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"OpenBook\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 15. BOOK COVER (aged leather - dark) ---\\\\nmat, nt = create_material(\\\\\\\"M_BookCover\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.12, 0.06, 0.03, 1.0)  # dark leather\\\\nbsdf.inputs['Roughness'].default_value = 0.65\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"BookCover\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- 16. ORANGES ---\\\\nmat, nt = create_material(\\\\\\\"M_Orange\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.75, 0.32, 0.06, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\n# Orange peel texture\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.5\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 60.0\\\\nnoise.inputs['Detail'].default_value = 2.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nfor name in [\\\\\\\"Orange1\\\\\\\", \\\\\\\"Orange2\\\\\\\"]:\\\\n    bpy.data.objects[name].data.materials.append(mat)\\\\n\\\\n# --- 17. LEMON ---\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['B'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Prop materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"materials\\\\\\\": [m.name for m in bpy.data.materials]}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a15057346df8e108\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 77, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"B\\\\\\\" not found'\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix lemon material - the noise output should be 'Fac' not 'B'\\\\nmat = bpy.data.materials.get(\\\\\\\"M_Lemon\\\\\\\")\\\\nif mat:\\\\n    bpy.data.materials.remove(mat)\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# Re-create lemon with correct output\\\\nmat, nt = create_material(\\\\\\\"M_Lemon\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.80, 0.65, 0.12, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.7\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.4\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise.inputs['Scale'].default_value = 80.0\\\\nnt.links.new(noise.outputs['Fac'], bump.inputs['Height'])  # Fixed: 'Fac'\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Lemon material fixed.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b29a2fe5c411d5a8\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Lemon material fixed.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the lighting — the chiaroscuro shaft of warm light. Then the camera.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# LIGHTING: Chiaroscuro — single warm shaft of light from one side\\\\n# ============================================================\\\\n\\\\n# --- Key light: warm window shaft from the left ---\\\\nbpy.ops.object.light_add(type='AREA', location=(-3.0, -1.0, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 800\\\\nkey_light.data.color = (1.0, 0.85, 0.6)  # warm tungsten\\\\nkey_light.data.size = 2.0\\\\nkey_light.data.size_y = 3.5\\\\nkey_light.rotation_euler = (math.radians(50), math.radians(-20), math.radians(20))\\\\n\\\\n# --- Fill light: very dim cool fill from right (just to lift shadows slightly) ---\\\\nbpy.ops.object.light_add(type='AREA', location=(3.0, 0.5, 2.5))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Cool\\\\\\\"\\\\nfill_light.data.energy = 30\\\\nfill_light.data.color = (0.6, 0.7, 0.9)  # cool blue\\\\nfill_light.data.size = 3.0\\\\nfill_light.rotation_euler = (math.radians(60), math.radians(20), math.radians(-30))\\\\n\\\\n# --- Rim light: subtle warm rim from behind to separate objects from background ---\\\\nbpy.ops.object.light_add(type='SPOT', location=(0, 2.5, 2.5))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight\\\\\\\"\\\\nrim_light.data.energy = 100\\\\nrim_light.data.color = (1.0, 0.8, 0.5)\\\\nrim_light.data.spot_size = math.radians(60)\\\\nrim_light.data.spot_blend = 0.8\\\\nrim_light.rotation_euler = (math.radians(120), 0, 0)\\\\n\\\\n# --- Window frame light (creates the shaft pattern) ---\\\\n# A narrow area light to simulate light coming through a window\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, 0.5, 2.8))\\\\nwindow_light = bpy.context.active_object\\\\nwindow_light.name = \\\\\\\"WindowLight\\\\\\\"\\\\nwindow_light.data.energy = 400\\\\nwindow_light.data.color = (1.0, 0.88, 0.65)\\\\nwindow_light.data.size = 0.8\\\\nwindow_light.data.size_y = 1.5\\\\nwindow_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(15))\\\\n\\\\nprint(\\\\\\\"Lighting set up.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b0d781dd9dc96405\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Cool\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight\\\",\\n      \\\"WindowLight\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me set up the camera at the intimate slightly-elevated angle of the genre, roughly 50mm equivalent.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# CAMERA: ~50mm equivalent, slightly elevated intimate angle\\\\n# ============================================================\\\\nbpy.ops.object.camera_add(location=(3.2, -3.8, 2.2))\\\\ncam = bpy.context.active_object\\\\ncam.name = \\\\\\\"Camera_Presentation\\\\\\\"\\\\ncam.data.lens = 50  # 50mm focal length\\\\ncam.data.sensor_width = 36  # full frame\\\\ncam.data.sensor_height = 36  # square format for 1536x1536\\\\n\\\\n# Point camera at the teapot (center of arrangement)\\\\ntarget = Vector((-0.1, 0.1, 0.4))  # slightly above table, at teapot height\\\\ndirection = target - cam.location\\\\n# Convert direction to rotation\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\n\\\\n# Set as active scene camera\\\\nbpy.context.scene.camera = cam\\\\n\\\\n# Depth of field - subtle, focused on teapot\\\\ncam.data.dof.use_dof = True\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\ncam.data.dof.aperture_fstop = 4.0\\\\n\\\\nprint(\\\\\\\"Camera set up.\\\\\\\")\\\\nresult = {\\\\n    \\\\\\\"camera_location\\\\\\\": list(cam.location),\\\\n    \\\\\\\"camera_rotation\\\\\\\": [math.degrees(r) for r in cam.rotation_euler],\\\\n    \\\\\\\"lens\\\\\\\": cam.data.lens,\\\\n    \\\\\\\"focus_distance\\\\\\\": cam.data.dof.focus_distance\\\\n}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81d514f5f212c1fe\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"camera_location\\\": [\\n      3.200000047683716,\\n      -3.799999952316284,\\n      2.200000047683716\\n    ],\\n    \\\"camera_rotation\\\": [\\n      70.59100910988977,\\n      -1.0795828508605228e-6,\\n      40.236364362789146\\n    ],\\n    \\\"lens\\\": 50.0,\\n    \\\"focus_distance\\\": 5.416640758514404\\n  },\\n  \\\"stdout\\\": \\\"Camera set up.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me do a quick render preview to see where we are, then I'll refine.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-80a032b133fec618\",\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_preview1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-80a032b133fec618\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_preview1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91107c27573cb421\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91107c27573cb421\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me look at the rendered image to evaluate.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Check what the render output looks like by examining the image\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\nprint(f\\\\\\\"Image size: {img.size[0]}x{img.size[1]}\\\\\\\")\\\\nprint(f\\\\\\\"Image channels: {img.channels}\\\\\\\")\\\\n# Get some pixel values to check if it's rendering properly\\\\npixels = list(img.pixels[:20])\\\\nprint(f\\\\\\\"First pixels: {pixels}\\\\\\\")\\\\nresult = {\\\\\\\"image_size\\\\\\\": list(img.size), \\\\\\\"loaded\\\\\\\": True}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-97c7b5546a1ad792\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"image_size\\\": [\\n      1536,\\n      1536\\n    ],\\n    \\\"loaded\\\": true\\n  },\\n  \\\"stdout\\\": \\\"Image size: 1536x1536\\\\nImage channels: 4\\\\nFirst pixels: [0.2549019753932953, 0.20000001788139343, 0.1568627506494522, 1.0, 0.27450981736183167, 0.20000001788139343, 0.1411764770746231, 1.0, 0.27450981736183167, 0.20000001788139343, 0.13333334028720856, 1.0, 0.27450981736183167, 0.2039215862751007, 0.13725490868091583, 1.0, 0.27843138575553894, 0.19607844948768616, 0.12941177189350128, 1.0]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a7524c48acac6867\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a7524c48acac6867\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"window_width\\\": 1920,\\n    \\\"window_height\\\": 1111,\\n    \\\"screen_name\\\": \\\"Layout\\\",\\n    \\\"workspace\\\": \\\"Layout\\\",\\n    \\\"scene\\\": \\\"Scene\\\",\\n    \\\"areas\\\": [\\n      {\\n        \\\"type\\\": \\\"PROPERTIES\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 854,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"PROPERTIES\\\",\\n          \\\"context\\\": \\\"OBJECT\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 851,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"NAVIGATION_BAR\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 36,\\n            \\\"height\\\": 822\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1615,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 303,\\n            \\\"height\\\": 822\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"OUTLINER\\\",\\n        \\\"x\\\": 1579,\\n        \\\"y\\\": 886,\\n        \\\"width\\\": 339,\\n        \\\"height\\\": 192,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"OUTLINER\\\",\\n          \\\"display_mode\\\": \\\"VIEW_LAYER\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 1579,\\n            \\\"y\\\": 886,\\n            \\\"width\\\": 339,\\n            \\\"height\\\": 160\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"DOPESHEET_EDITOR\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 29,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 75,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"DOPESHEET_EDITOR\\\"\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 72,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"FOOTER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"CHANNELS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 29,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 43\\n          }\\n        ]\\n      },\\n      {\\n        \\\"type\\\": \\\"VIEW_3D\\\",\\n        \\\"x\\\": 2,\\n        \\\"y\\\": 107,\\n        \\\"width\\\": 1574,\\n        \\\"height\\\": 971,\\n        \\\"space\\\": {\\n          \\\"type\\\": \\\"VIEW_3D\\\",\\n          \\\"view_perspective\\\": \\\"PERSP\\\",\\n          \\\"view_location\\\": [\\n            -0.020693248137831688,\\n            -0.04602546989917755,\\n            0.0006694307667203248\\n          ],\\n          \\\"shading_type\\\": \\\"SOLID\\\",\\n          \\\"show_overlays\\\": true\\n        },\\n        \\\"regions\\\": [\\n          {\\n            \\\"type\\\": \\\"HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1046,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOL_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 1014,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 32\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"ASSET_SHELF_HEADER\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"TOOLS\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 70,\\n            \\\"height\\\": 907\\n          },\\n          {\\n            \\\"type\\\": \\\"UI\\\",\\n            \\\"x\\\": 1575,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"HUD\\\",\\n            \\\"x\\\": 72,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1,\\n            \\\"height\\\": 1\\n          },\\n          {\\n            \\\"type\\\": \\\"WINDOW\\\",\\n            \\\"x\\\": 2,\\n            \\\"y\\\": 107,\\n            \\\"width\\\": 1574,\\n            \\\"height\\\": 971\\n          }\\n        ]\\n      }\\n    ],\\n    \\\"active_object\\\": {\\n      \\\"name\\\": \\\"Camera_Presentation\\\",\\n      \\\"type\\\": \\\"CAMERA\\\",\\n      \\\"mode\\\": \\\"OBJECT\\\",\\n      \\\"location\\\": [\\n        3.200000047683716,\\n        -3.799999952316284,\\n        2.200000047683716\\n      ]\\n    },\\n    \\\"selected_objects\\\": [\\n      {\\n        \\\"name\\\": \\\"Camera_Presentation\\\",\\n        \\\"type\\\": \\\"CAMERA\\\"\\n      }\\n    ],\\n    \\\"message\\\": null\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":\"Let me switch to the rendered view to see the output.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n# Set viewport to rendered mode to see the result\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'VIEW_3D':\\\\n        for space in area.spaces:\\\\n            if space.type == 'VIEW_3D':\\\\n                space.shading.type = 'RENDERED'\\\\n                break\\\\n        break\\\\nprint(\\\\\\\"Set viewport to rendered\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8e4c646f6f5eaca4\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Set viewport to rendered\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-879a01af15b1da65\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-879a01af15b1da65\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me examine the rendered preview more closely by sampling pixel values across the image to understand the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_preview1.png\\\\\\\")\\\\nif img is None:\\\\n    # Load the rendered image\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_preview1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Sample various regions of the image\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            r_sum += pixels[idx]\\\\n            g_sum += pixels[idx+1]\\\\n            b_sum += pixels[idx+2]\\\\n            count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f}\\\\\\\")\\\\n    return r_avg, g_avg, b_avg\\\\n\\\\n# Sample center, corners, and regions\\\\nsample_region(0, 0, w//4, h//4, \\\\\\\"Top-left (bg)\\\\\\\")\\\\nsample_region(3*w//4, 3*h//4, w, h, \\\\\\\"Bottom-right (fg)\\\\\\\")\\\\nsample_region(w//3, h//3, 2*w//3, 2*h//3, \\\\\\\"Center (objects)\\\\\\\")\\\\nsample_region(0, 3*h//4, w//4, h, \\\\\\\"Bottom-left\\\\\\\")\\\\nsample_region(3*w//4, 0, w, h//4, \\\\\\\"Top-right\\\\\\\")\\\\n\\\\n# Check overall brightness\\\\ntotal_bright = sum(pixels[i] + pixels[i+1] + pixels[i+2] for i in range(0, len(pixels), 4*100))\\\\nprint(f\\\\\\\"\\\\\\\\nOverall brightness sample: {total_bright / (len(pixels)//(4*100) * 3):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac3fa7e5b9d09b8b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Top-left (bg): R=0.280 G=0.219 B=0.149\\\\nBottom-right (fg): R=0.688 G=0.618 B=0.496\\\\nCenter (objects): R=0.518 G=0.470 B=0.384\\\\nBottom-left: R=0.084 G=0.061 B=0.050\\\\nTop-right: R=0.217 G=0.411 B=0.143\\\\n\\\\nOverall brightness sample: 0.407\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working. I can see the green panel on the right and objects in the center. Let me do a proper render to evaluate the full composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-921480628bdd2acf\",\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"arguments\":\"{\\\"output_path\\\": \\\"C:/tmp/still_life_render1.png\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-921480628bdd2acf\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"filepath\\\": \\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Temp\\\\\\\\blender_a87204\\\\\\\\blender_mcp\\\\\\\\still_life_render1.png\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-af37df6737703d4f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimg = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check more regions to understand composition\\\\ndef sample_region(x_start, y_start, x_end, y_end, label):\\\\n    r_sum, g_sum, b_sum, count = 0, 0, 0, 0\\\\n    for y in range(y_start, y_end, 10):\\\\n        for x in range(x_start, x_end, 10):\\\\n            idx = (y * w + x) * 4\\\\n            if idx + 2 < len(pixels):\\\\n                r_sum += pixels[idx]\\\\n                g_sum += pixels[idx+1]\\\\n                b_sum += pixels[idx+2]\\\\n                count += 1\\\\n    r_avg = r_sum / count if count > 0 else 0\\\\n    g_avg = g_sum / count if count > 0 else 0\\\\n    b_avg = b_sum / count if count > 0 else 0\\\\n    print(f\\\\\\\"{label}: R={r_avg:.3f} G={g_avg:.3f} B={b_avg:.3f} bright={sum([r_avg,g_avg,b_avg])/3:.3f}\\\\\\\")\\\\n\\\\n# Grid sampling\\\\nfor gy in range(4):\\\\n    for gx in range(4):\\\\n        x1 = gx * w // 4\\\\n        x2 = (gx+1) * w // 4\\\\n        y1 = gy * h // 4\\\\n        y2 = (gy+1) * h // 4\\\\n        sample_region(x1, y1, x2, y2, f\\\\\\\"Grid[{gx},{gy}]\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-af37df6737703d4f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Grid[0,0]: R=0.280 G=0.219 B=0.149 bright=0.216\\\\nGrid[1,0]: R=0.433 G=0.351 B=0.256 bright=0.347\\\\nGrid[2,0]: R=0.398 G=0.406 B=0.244 bright=0.349\\\\nGrid[3,0]: R=0.217 G=0.411 B=0.143 bright=0.257\\\\nGrid[0,1]: R=0.832 G=0.626 B=0.528 bright=0.662\\\\nGrid[1,1]: R=0.658 G=0.619 B=0.545 bright=0.607\\\\nGrid[2,1]: R=0.455 G=0.402 B=0.281 bright=0.379\\\\nGrid[3,1]: R=0.316 G=0.465 B=0.244 bright=0.342\\\\nGrid[0,2]: R=0.335 G=0.274 B=0.221 bright=0.276\\\\nGrid[1,2]: R=0.628 G=0.520 B=0.444 bright=0.531\\\\nGrid[2,2]: R=0.475 G=0.411 B=0.312 bright=0.400\\\\nGrid[3,2]: R=0.557 G=0.493 B=0.383 bright=0.478\\\\nGrid[0,3]: R=0.084 G=0.061 B=0.050 bright=0.065\\\\nGrid[1,3]: R=0.786 G=0.596 B=0.508 bright=0.630\\\\nGrid[2,3]: R=0.429 G=0.359 B=0.268 bright=0.352\\\\nGrid[3,3]: R=0.688 G=0.618 B=0.496 bright=0.601\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9e8d1c3844120289\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\n# Let me analyze the composition more carefully\\\\n# The grid shows: left side has warm light, right side has green, center has objects\\\\n# Bottom-left is very dark (good for chiaroscuro)\\\\n# Let me check if objects are visible and well-placed\\\\n\\\\nimport bpy\\\\nimg = bpy.data.images.get(\\\\\\\"still_life_render1.png\\\\\\\")\\\\nif img is None:\\\\n    img = bpy.data.images.load(\\\\\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\proud\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\blender_a87204\\\\\\\\\\\\\\\\blender_mcp\\\\\\\\\\\\\\\\still_life_render1.png\\\\\\\")\\\\n\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Check for the teapot area (should be center-ish, bright ceramic)\\\\n# Camera is at (3.2, -3.8, 2.2) looking at (-0.1, 0.1, 0.4)\\\\n# Teapot is at world (-0.1, 0.1, 0) - should be roughly center of frame\\\\n\\\\n# Let me check if we can see bright highlights (ceramic teapot)\\\\nbright_count = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.8 and g > 0.7 and b > 0.6:\\\\n        bright_count += 1\\\\n\\\\nprint(f\\\\\\\"Bright highlight pixels: {bright_count} / {len(pixels)//4} ({100*bright_count/(len(pixels)//4):.1f}%)\\\\\\\")\\\\n\\\\n# Check if the sphere is visible (should be dark/light checker pattern)\\\\n# Check middle-bottom area\\\\nmid_bot_bright = 0\\\\nfor y in range(int(h*0.4), int(h*0.6)):\\\\n    for x in range(int(w*0.4), int(w*0.6)):\\\\n        idx = (y * w + x) * 4\\\\n        mid_bot_bright += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\nprint(f\\\\\\\"Center brightness avg: {mid_bot_bright / (int(w*0.2) * int(h*0.2)):.3f}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\", \\\\\\\"bright_pixels_pct\\\\\\\": 100*bright_count/(len(pixels)//4)}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9e8d1c3844120289\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\",\\n    \\\"bright_pixels_pct\\\": 11.747021145290798\\n  },\\n  \\\"stdout\\\": \\\"Bright highlight pixels: 277147 / 2359296 (11.7%)\\\\nCenter brightness avg: 0.518\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The render is working well. I can see bright highlights from the ceramic teapot and objects are visible. Let me now look at the actual rendered image to evaluate the composition visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8a435cbbf4d6dda0\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me check the modifier stack on the bunny and verify all objects are rendering properly, then make refinements.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check all objects and their modifiers\\\\nfor obj in bpy.data.objects:\\\\n    if obj.type == 'MESH':\\\\n        mods = [(m.name, m.type) for m in obj.modifiers]\\\\n        mats = [m.name for m in obj.data.materials] if obj.data.materials else []\\\\n        print(f\\\\\\\"{obj.name}: loc={list(obj.location)}, scale={list(obj.scale)}, mods={mods}, mats={mats}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a0fd0dc86e72eae1\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"BackWall: loc=[0.0, 2.5, 2.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BackWall']\\\\nBookCover: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookCover']\\\\nCheckeredSphere: loc=[0.15000000596046448, -0.550000011920929, 0.2199999988079071], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_CheckeredSphere']\\\\nFloor: loc=[0.0, -3.0, -0.20000000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Floor']\\\\nGreenCloth: loc=[2.0, 0.30000001192092896, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_GreenVelvet.001']\\\\nGreenPanel: loc=[2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_GreenPanel']\\\\nLemon1: loc=[0.699999988079071, -0.550000011920929, 0.07999999821186066], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Lemon']\\\\nOpenBook: loc=[-0.6000000238418579, -0.699999988079071, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BookPages']\\\\nOrange1: loc=[0.8500000238418579, -0.75, 0.09000000357627869], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nOrange2: loc=[1.0499999523162842, -0.6499999761581421, 0.07500000298023224], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_Orange']\\\\nRedCloth: loc=[-2.200000047683716, -1.5, 0.019999999552965164], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_RedVelvet', 'M_RedVelvet.001']\\\\nRedPanel: loc=[-2.799999952316284, 1.7999999523162842, 2.200000047683716], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_RedPanel']\\\\nStanfordBunny: loc=[-1.149999976158142, 0.25, 0.029999999329447746], scale=[1.2999999523162842, 1.2999999523162842, 1.2999999523162842], mods=[('Remesh', 'REMESH'), ('Subsurf', 'SUBSURF')], mats=['M_BunnyBronze']\\\\nSuzanne: loc=[1.0, -0.05000000074505806, 0.18000000715255737], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_SuzanneMarble']\\\\nSuzanneBase: loc=[0.0, 0.0, -0.15000000596046448], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_BustBase']\\\\nTableEdge: loc=[0.0, -1.75, -0.05000000074505806], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTableTop: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[], mats=['M_TableTop']\\\\nTeapotBody: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotHandle: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotLid: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nTeapotSpout: loc=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], mods=[('Subsurf', 'SUBSURF')], mats=['M_TeapotCeramic']\\\\nWhiteCloth: loc=[0.0, -0.20000000298023224, 0.029999999329447746], scale=[1.0, 1.0, 1.0], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WhiteLinen']\\\\nWineGlass: loc=[1.5499999523162842, 0.30000001192092896, 0.0], scale=[1.100000023841858, 1.100000023841858, 1.100000023841858], mods=[('Solidify', 'SOLIDIFY')], mats=['M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see some material duplication issues. Let me clean those up and make refinements to improve the scene.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-975cf092ec3d5919\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Fix material assignments - clean up duplicates\\\\n# RedCloth has both M_RedVelvet and M_RedVelvet.001\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\nred_cloth.data.materials.clear()\\\\nred_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"])\\\\n\\\\n# GreenCloth has M_GreenVelvet.001 instead of M_GreenVelvet\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\ngreen_cloth.data.materials.clear()\\\\ngreen_cloth.data.materials.append(bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"])\\\\n\\\\n# Remove duplicate materials\\\\nfor mat_name in [\\\\\\\"M_RedVelvet.001\\\\\\\", \\\\\\\"M_GreenVelvet.001\\\\\\\"]:\\\\n    mat = bpy.data.materials.get(mat_name)\\\\n    if mat:\\\\n        bpy.data.materials.remove(mat)\\\\n\\\\n# Verify\\\\nfor name in [\\\\\\\"RedCloth\\\\\\\", \\\\\\\"GreenCloth\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    print(f\\\\\\\"{name}: {[m.name for m in obj.data.materials]}\\\\\\\")\\\\n\\\\nprint(f\\\\\\\"\\\\\\\\nAll materials: {[m.name for m in bpy.data.materials]}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-975cf092ec3d5919\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"RedCloth: ['M_RedVelvet']\\\\nGreenCloth: ['M_GreenVelvet']\\\\n\\\\nAll materials: ['M_BackWall', 'M_BookCover', 'M_BookPages', 'M_BunnyBronze', 'M_BustBase', 'M_CheckeredSphere', 'M_Floor', 'M_GreenPanel', 'M_GreenVelvet', 'M_Lemon', 'M_Orange', 'M_RedPanel', 'M_RedVelvet', 'M_SuzanneMarble', 'M_TableTop', 'M_TeapotCeramic', 'M_WhiteLinen', 'M_WineGlass']\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good. Now let me check the Suzanne bust - the base needs to be positioned properly under Suzanne.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# Fix Suzanne base positioning\\\\n# Suzanne is at (1.0, -0.05, 0.18), she's size=0.5 monkey\\\\n# The base should be under her, on the table\\\\n\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\n\\\\n# Suzanne's monkey head bottom is around z=0.0 in local space (since size=0.5)\\\\n# She's at z=0.18, so her bottom is at about z=0.18 - 0.1 = 0.08\\\\n# Place base right under her\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.03)\\\\nbase.scale = (1.0, 1.0, 1.0)\\\\n\\\\n# Make sure Suzanne is resting on the base\\\\nsuzanne.location.z = 0.18\\\\n\\\\n# Apply Suzanne's rotation to the base too\\\\nbase.rotation_euler = (0, 0, 0)\\\\n\\\\nprint(f\\\\\\\"Suzanne: {list(suzanne.location)}\\\\\\\")\\\\nprint(f\\\\\\\"Base: {list(base.location)}\\\\\\\")\\\\n\\\\n# Now let me also check the bunny - make sure it sits on the table\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\n# The bunny's lowest point should be at z=0 (table surface)\\\\n# With scale 1.3, the body parts go from z=0 to about z=0.6*1.3=0.78\\\\n# Let's check its bounding box\\\\nbunny.evaluated_get(bpy.context.evaluated_depsgraph_get())\\\\n# The bunny was built with parts at z=0 to ~0.6, then scaled 1.3\\\\n# Lowest parts are the paws at z=0, so it should sit on table\\\\nbunny.location.z = 0.03  # slight lift for cloth thickness\\\\n\\\\n# Adjust bunny rotation so it faces slightly toward camera\\\\nbunny.rotation_euler = (0, 0, math.radians(40))\\\\n\\\\nprint(f\\\\\\\"Bunny: {list(bunny.location)}\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a250101a80c6b1b3\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne: [1.0, -0.05000000074505806, 0.18000000715255737]\\\\nBase: [1.0, -0.05000000074505806, 0.029999999329447746]\\\\nBunny: [-1.149999976158142, 0.25, 0.029999999329447746]\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me do a proper render to evaluate the full composition. I'll reduce samples temporarily for faster feedback.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b61f025e64068731\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Temporarily reduce samples for faster preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\n\\\\n# Set render output\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\"\\\\n\\\\n# Render\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nprint(\\\\\\\"Preview render complete.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b61f025e64068731\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Preview render complete.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-838028367162311c\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed grid analysis\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (4x6 grid):\\\\\\\")\\\\nfor gy in range(6):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(6):\\\\n        x1 = gx * w // 6\\\\n        x2 = (gx+1) * w // 6\\\\n        y1 = gy * h // 6\\\\n        y2 = (gy+1) * h // 6\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 15):\\\\n            for x in range(x1, x2, 15):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        # Create ASCII brightness map\\\\n        if bright < 0.1: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"☀ \\\\\\\"\\\\n        elif bright < 0.6: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-838028367162311c\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (4x6 grid):\\\\n  Row 0: |• · • •     |\\\\n  Row 1: |○ ▓ ▒ ☀ ·   |\\\\n  Row 2: |▒ █ ☀ ○ ○ · |\\\\n  Row 3: |○ ☀ ▒ ☀ ☀ ☀ |\\\\n  Row 4: |  ○ ▓ • ▒ ▓ |\\\\n  Row 5: |  ☀ ▓ • ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I can see the composition is taking shape - bright objects in the center and lower-left, with the table edge visible at the bottom. Let me view the actual screenshot now.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8890c007fcce85eb\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Set the render output to show in the image editor\\\\nfor area in bpy.context.screen.areas:\\\\n    if area.type == 'IMAGE_EDITOR':\\\\n        for space in area.spaces:\\\\n            if space.type == 'IMAGE_EDITOR':\\\\n                img = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview2.png\\\\\\\")\\\\n                space.image = img\\\\n                break\\\\n        break\\\\n\\\\n# Also try to view it in the 3D viewport as background\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8890c007fcce85eb\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  }\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a31aecfdef27c07a\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me make significant improvements to the scene. I'll refine the lighting for better chiaroscuro, improve the teapot material, and adjust the composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REFINEMENTS: Better lighting, composition, and materials\\\\n# ============================================================\\\\n\\\\n# --- 1. Improve lighting for stronger chiaroscuro ---\\\\n# Remove existing lights\\\\nfor obj in list(bpy.data.objects):\\\\n    if obj.type == 'LIGHT':\\\\n        bpy.data.objects.remove(obj, do_unlink=True)\\\\n\\\\n# Key light: warm window shaft from upper-left, more dramatic\\\\nbpy.ops.object.light_add(type='AREA', location=(-2.5, -0.5, 3.5))\\\\nkey_light = bpy.context.active_object\\\\nkey_light.name = \\\\\\\"KeyLight_WarmShaft\\\\\\\"\\\\nkey_light.data.energy = 1200\\\\nkey_light.data.color = (1.0, 0.82, 0.55)  # warm candle/window light\\\\nkey_light.data.size = 1.5\\\\nkey_light.data.size_y = 2.5\\\\nkey_light.rotation_euler = (math.radians(55), math.radians(-15), math.radians(25))\\\\n\\\\n# Very subtle fill from right to prevent total blackness\\\\nbpy.ops.object.light_add(type='AREA', location=(3.5, 1.0, 2.0))\\\\nfill_light = bpy.context.active_object\\\\nfill_light.name = \\\\\\\"FillLight_Dim\\\\\\\"\\\\nfill_light.data.energy = 15\\\\nfill_light.data.color = (0.5, 0.6, 0.8)\\\\nfill_light.data.size = 4.0\\\\nfill_light.rotation_euler = (math.radians(70), math.radians(15), math.radians(-40))\\\\n\\\\n# Subtle warm rim from behind-right to separate objects\\\\nbpy.ops.object.light_add(type='AREA', location=(1.5, 2.5, 2.0))\\\\nrim_light = bpy.context.active_object\\\\nrim_light.name = \\\\\\\"RimLight_Warm\\\\\\\"\\\\nrim_light.data.energy = 40\\\\nrim_light.data.color = (1.0, 0.75, 0.4)\\\\nrim_light.data.size = 2.0\\\\nrim_light.rotation_euler = (math.radians(100), 0, math.radians(-20))\\\\n\\\\n# --- 2. Add a window frame to create light shaft pattern ---\\\\n# Window frame (dark wood, partially visible on left)\\\\nbpy.ops.mesh.primitive_cube_add(size=1, location=(-3.2, -0.5, 2.5))\\\\nwindow_frame = bpy.context.active_object\\\\nwindow_frame.name = \\\\\\\"WindowFrame\\\\\\\"\\\\nwindow_frame.scale = (0.1, 2.0, 3.0)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\n\\\\n# Assign dark wood material\\\\nwindow_frame.data.materials.append(bpy.data.materials[\\\\\\\"M_TableTop\\\\\\\"])\\\\n\\\\n# --- 3. Adjust camera for better composition ---\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.5, -4.0, 2.0)\\\\ntarget = Vector((-0.1, 0.0, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Lighting and camera refined.\\\\\\\")\\\\nresult = {\\\\\\\"lights\\\\\\\": [o.name for o in bpy.data.objects if o.type == 'LIGHT']}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a6b2fe3e89402cda\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"lights\\\": [\\n      \\\"FillLight_Dim\\\",\\n      \\\"KeyLight_WarmShaft\\\",\\n      \\\"RimLight_Warm\\\"\\n    ]\\n  },\\n  \\\"stdout\\\": \\\"Lighting and camera refined.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-938e608ed2771955\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview with improved lighting\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.cycles.use_denoising = True\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze the result\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview3.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(f\\\\\\\"Image: {w}x{h}\\\\\\\")\\\\nprint(\\\\\\\"\\\\\\\\nBrightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-938e608ed2771955\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Image: 1536x1536\\\\n\\\\nBrightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |· · • ○ ○       |\\\\n  Row 2: |○ ▓ ▒ ▒ ▓ •     |\\\\n  Row 3: |▒ █ █ ○ ○ ● ○ · |\\\\n  Row 4: |● ● ▓ █ ▓ ● ● ● |\\\\n  Row 5: |·   • ▓ ○ ▒ ▒ ▓ |\\\\n  Row 6: |█ • ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |█ • ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8421787e6475ccad\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8421787e6475ccad\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The brightness map shows the objects are concentrated in the center with the warm light from the left. I can see the table edge at the bottom and the composition is forming. Let me now make significant refinements: improve the teapot material to be more silver/ceramic, fix the wine glass to contain wine, and enhance the cloth draping.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf8158560fd480f6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE TEAPOT MATERIAL: Silver/Vermeer ceramic with aged patina\\\\n# ============================================================\\\\nmat, nt = create_material(\\\\\\\"M_TeapotSilver\\\\\\\")\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\n\\\\n# Silver-ish base with warm ceramic undertones\\\\nbsdf.inputs['Base Color'].default_value = (0.82, 0.78, 0.72, 1.0)\\\\nbsdf.inputs['Metallic'].default_value = 0.7\\\\nbsdf.inputs['Roughness'].default_value = 0.22\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Color variation: silver to warmer bronze areas\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 6.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (0, 200))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.72, 0.66, 0.55, 1.0)  # warmer bronze\\\\ncolor_ramp.color_ramp.elements[1].color = (0.85, 0.82, 0.76, 1.0)  # silver\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Metallic variation\\\\ncolor_ramp2 = add_node(nt, 'ShaderNodeValToRGB', (0, 0))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp2.inputs['Fac'])\\\\ncolor_ramp2.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1.0)  # less metallic (bronze)\\\\ncolor_ramp2.color_ramp.elements[1].color = (0.85, 0.85, 0.85, 1.0)  # more metallic (silver)\\\\nnt.links.new(color_ramp2.outputs['Color'], bsdf.inputs['Metallic'])\\\\n\\\\n# Subtle surface bump for aged feel\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -150))\\\\nbump.inputs['Strength'].default_value = 0.1\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (-200, -150))\\\\nnoise3.inputs['Scale'].default_value = 60.0\\\\nnoise3.inputs['Detail'].default_value = 8.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\n# Assign to all teapot parts\\\\nfor name in [\\\\\\\"TeapotBody\\\\\\\", \\\\\\\"TeapotSpout\\\\\\\", \\\\\\\"TeapotHandle\\\\\\\", \\\\\\\"TeapotLid\\\\\\\"]:\\\\n    obj = bpy.data.objects[name]\\\\n    obj.data.materials.clear()\\\\n    obj.data.materials.append(mat)\\\\n\\\\n# Remove old material\\\\nold = bpy.data.materials.get(\\\\\\\"M_TeapotCeramic\\\\\\\")\\\\nif old:\\\\n    bpy.data.materials.remove(old)\\\\n\\\\nprint(\\\\\\\"Teapot silver material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf8158560fd480f6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Teapot silver material improved.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE WINE GLASS: Add red wine inside\\\\n# ============================================================\\\\n# Create a separate wine liquid mesh inside the glass\\\\nimport bmesh\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WineLiquidMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of wine surface (a lathed bowl shape, slightly smaller than glass)\\\\nwine_profile = [\\\\n    (0.00, 0.30),    # center bottom\\\\n    (0.06, 0.30),    # \\\\n    (0.08, 0.31),    # \\\\n    (0.10, 0.32),    # \\\\n    (0.11, 0.34),    # bowl\\\\n    (0.12, 0.36),    # \\\\n    (0.125, 0.38),   # \\\\n    (0.12, 0.40),    # \\\\n    (0.11, 0.42),    # \\\\n    (0.10, 0.44),    # wine surface level\\\\n    (0.00, 0.44),    # center top (wine surface)\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in wine_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = wine_profile[ri]\\\\n    rb, _ = wine_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            # Cap the top (wine surface)\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwine_obj = bpy.data.objects.new(\\\\\\\"WineLiquid\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(wine_obj)\\\\nwine_obj.location = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].location.copy()\\\\nwine_obj.scale = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].scale.copy()\\\\nwine_obj.rotation_euler = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"].rotation_euler.copy()\\\\n\\\\n# Wine material - deep red, slightly translucent\\\\nmat, nt = create_material(\\\\\\\"M_RedWine\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.35, 0.02, 0.03, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.1\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\nbsdf.inputs['Transmission Weight'].default_value = 0.3\\\\nbsdf.inputs['IOR'].default_value = 1.33\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nwine_obj.data.materials.append(mat)\\\\n\\\\nprint(\\\\\\\"Wine liquid added to glass.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ae3e4ac817118e18\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Wine liquid added to glass.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me improve the cloth draping and add more fold structure. Let me also enhance the back wall to feel more like a Dutch painting.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(7)\\\\n\\\\n# ============================================================\\\\n# IMPROVE CLOTH FOLDS: More dramatic draping\\\\n# ============================================================\\\\n\\\\n# Rebuild the red cloth with better draping (hanging off table edge)\\\\nred_cloth = bpy.data.objects[\\\\\\\"RedCloth\\\\\\\"]\\\\n# Remove and rebuild\\\\nbpy.data.objects.remove(red_cloth, do_unlink=True)\\\\nmat_red = bpy.data.materials[\\\\\\\"M_RedVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"RedClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Create a cloth that drapes over the left edge of the table\\\\n# Grid of vertices\\\\ncols = 50\\\\nrows = 40\\\\nwidth = 3.5\\\\nlength = 3.5\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Create folds: the cloth hangs off the front edge (y < -0.5)\\\\n        # and has ripple folds on the table surface\\\\n        if y < -0.5:\\\\n            # Hanging down over the edge\\\\n            edge_dist = abs(y + 0.5)\\\\n            z = -edge_dist * 0.8\\\\n            # Add vertical folds in the hanging part\\\\n            z += 0.05 * math.sin(x * 8) * min(1.0, edge_dist * 2)\\\\n        else:\\\\n            # On the table: gentle ripples\\\\n            z = 0.02 * math.sin(x * 6 + y * 3)\\\\n            z += 0.015 * math.cos(y * 8)\\\\n        \\\\n        # Add noise for natural variation\\\\n        z += random.uniform(-0.01, 0.01)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\n# Create faces\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nred_cloth = bpy.data.objects.new(\\\\\\\"RedCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(red_cloth)\\\\nred_cloth.location = (-1.8, -0.3, 0.01)\\\\nbpy.context.view_layer.objects.active = red_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Add solidify\\\\nmod = red_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\n# Add subsurf for smoothness\\\\nmod2 = red_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nred_cloth.data.materials.append(mat_red)\\\\n\\\\nprint(\\\\\\\"Red cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-bf5e612aba0a0b79\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-90e8b33148374071\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(8)\\\\n\\\\n# Rebuild green cloth with better draping\\\\ngreen_cloth = bpy.data.objects[\\\\\\\"GreenCloth\\\\\\\"]\\\\nbpy.data.objects.remove(green_cloth, do_unlink=True)\\\\nmat_green = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"GreenClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 40\\\\nwidth = 3.0\\\\nlength = 3.0\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Green cloth on right side, draped with folds\\\\n        # The back part rises slightly (against the wall)\\\\n        if y > 0.8:\\\\n            z = (y - 0.8) * 0.3\\\\n        else:\\\\n            z = 0.02 * math.sin(x * 5 + y * 4)\\\\n            z += 0.015 * math.cos(y * 7)\\\\n        \\\\n        z += random.uniform(-0.008, 0.008)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\ngreen_cloth = bpy.data.objects.new(\\\\\\\"GreenCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(green_cloth)\\\\ngreen_cloth.location = (1.8, 0.5, 0.01)\\\\ngreen_cloth.rotation_euler = (0, 0, math.radians(-5))\\\\nbpy.context.view_layer.objects.active = green_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = green_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.012\\\\nmod.offset = 0\\\\n\\\\nmod2 = green_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\ngreen_cloth.data.materials.append(mat_green)\\\\n\\\\nprint(\\\\\\\"Green cloth rebuilt with better draping.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-90e8b33148374071\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Green cloth rebuilt with better draping.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nimport random\\\\nfrom mathutils import Vector\\\\n\\\\nrandom.seed(9)\\\\n\\\\n# Rebuild white/neutral linen runner\\\\nwhite_cloth = bpy.data.objects[\\\\\\\"WhiteCloth\\\\\\\"]\\\\nbpy.data.objects.remove(white_cloth, do_unlink=True)\\\\nmat_white = bpy.data.materials[\\\\\\\"M_WhiteLinen\\\\\\\"]\\\\n\\\\nmesh = bpy.data.meshes.new(\\\\\\\"WhiteClothMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\ncols = 40\\\\nrows = 35\\\\nwidth = 2.5\\\\nlength = 2.2\\\\n\\\\nverts_grid = []\\\\nfor ri in range(rows + 1):\\\\n    row = []\\\\n    for ci in range(cols + 1):\\\\n        x = (ci / cols - 0.5) * width\\\\n        y = (ri / rows - 0.5) * length\\\\n        z = 0.0\\\\n        \\\\n        # Linen runner with subtle folds\\\\n        z = 0.015 * math.sin(x * 4 + y * 2)\\\\n        z += 0.01 * math.cos(y * 6)\\\\n        # Slight droop at front edge\\\\n        if y < -0.7:\\\\n            z -= (abs(y) - 0.7) * 0.3\\\\n        \\\\n        z += random.uniform(-0.005, 0.005)\\\\n        \\\\n        v = bm.verts.new((x, y, z))\\\\n        row.append(v)\\\\n    verts_grid.append(row)\\\\n\\\\nfor ri in range(rows):\\\\n    for ci in range(cols):\\\\n        v1 = verts_grid[ri][ci]\\\\n        v2 = verts_grid[ri][ci+1]\\\\n        v3 = verts_grid[ri+1][ci+1]\\\\n        v4 = verts_grid[ri+1][ci]\\\\n        bm.faces.new([v1, v2, v3, v4])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nwhite_cloth = bpy.data.objects.new(\\\\\\\"WhiteCloth\\\\\\\", mesh)\\\\nbpy.context.scene.collection.objects.link(white_cloth)\\\\nwhite_cloth.location = (0.0, -0.1, 0.015)\\\\nbpy.context.view_layer.objects.active = white_cloth\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = white_cloth.modifiers.new(\\\\\\\"Solidify\\\\\\\", 'SOLIDIFY')\\\\nmod.thickness = 0.008\\\\nmod.offset = 0\\\\n\\\\nmod2 = white_cloth.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod2.levels = 1\\\\nmod2.render_levels = 2\\\\n\\\\nwhite_cloth.data.materials.append(mat_white)\\\\n\\\\nprint(\\\\\\\"White linen cloth rebuilt.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-957c0db57cb79a8e\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"White linen cloth rebuilt.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Now let me render a preview to check the improved composition.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-8f408822e950583f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\n# Analyze\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview4.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (8x8 grid):\\\\\\\")\\\\nfor gy in range(8):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(8):\\\\n        x1 = gx * w // 8\\\\n        x2 = (gx+1) * w // 8\\\\n        y1 = gy * h // 8\\\\n        y2 = (gy+1) * h // 8\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 20):\\\\n            for x in range(x1, x2, 20):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.08: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.15: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.25: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.35: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.45: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8f408822e950583f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (8x8 grid):\\\\n  Row 0: |· ·     · • • · |\\\\n  Row 1: |·   • ○ ○ •     |\\\\n  Row 2: |○ ▓ ▓ ● ○ •   · |\\\\n  Row 3: |▒ ▒ ▒ • • ● • • |\\\\n  Row 4: |● ▓ ▓ ▒ ● ● ● ○ |\\\\n  Row 5: |·   • ▓ • ▒ ▒ ▓ |\\\\n  Row 6: |● · ● ▒ · ▒ ▒ ▓ |\\\\n  Row 7: |▒ · ▓ ▒ · ▒ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-82aa10aa5a9e7a68\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"Let me refine the composition and positioning of objects, then improve the checkered sphere to be more reflective.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# REPOSITION OBJECTS FOR BETTER COMPOSITION\\\\n# Teapot is hero (center), overlapping depth arrangement\\\\n# ============================================================\\\\n\\\\n# Teapot - hero, center, commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.1, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-20))\\\\nteapot.scale = (0.9, 0.9, 0.9)\\\\n\\\\n# Stanford Bunny - left of teapot, slightly behind\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.1, 0.3, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(10), math.radians(35))\\\\nbunny.scale = (1.2, 1.2, 1.2)\\\\n\\\\n# Suzanne - right side, as bust portrait gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.1, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(10), math.radians(-5), math.radians(75))\\\\n\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Checkered sphere - front-center, slightly to right of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.3, -0.7, 0.22)\\\\n\\\\n# Wine glass - far right, behind Suzanne\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.7, 0.5, 0.0)\\\\nglass.scale = (1.1, 1.1, 1.1)\\\\n\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\nwine.scale = glass.scale.copy()\\\\n\\\\n# Open book - left-front, partially under bunny\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.5, -0.8, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(20))\\\\n\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit cluster - front-right, near Suzanne\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.9, -0.8, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].rotation_euler = (0, 0, math.radians(30))\\\\n\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.1, -0.7, 0.075)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].rotation_euler = (math.radians(20), 0, math.radians(15))\\\\n\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.75, -0.65, 0.08)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].rotation_euler = (math.radians(15), 0, math.radians(50))\\\\n\\\\n# Camera - slightly elevated, 50mm equivalent\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.2, -4.2, 2.0)\\\\ntarget = Vector((0.1, -0.1, 0.35))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\nprint(\\\\\\\"Objects repositioned for composition.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-b4fbfa633bfd27a6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Objects repositioned for composition.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check composition\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-91bf4a1a9b72901d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |· · ·       · · • • |\\\\n  Row 1: |• ·   · • ○ ○ • • • |\\\\n  Row 2: |· • ● ● ● ○ ○ ·     |\\\\n  Row 3: |▓ ▒ ▒ ▓ • • •     • |\\\\n  Row 4: |█ █ █ ▒ · · ○ • • · |\\\\n  Row 5: |▒ █ █ █ ▒ ○ ● ○ • ○ |\\\\n  Row 6: |  · • ● ▒ ▓ ▒ ▒ ▒ ▓ |\\\\n  Row 7: |•   ▓ ▒ ○ ○ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |○   ▒ █ ○ ○ █ ▒ ▒ ▒ |\\\\n  Row 9: |●   ▒ █ ○ ○ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good - I can see objects grouped in the center with warm light from the left and the green panel on the right. The table edge is visible at the bottom. Let me now look at the actual image to assess it visually.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a3cf445099275d43\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a3cf445099275d43\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8805a99244b0b994\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Let me check the image more carefully by saving a smaller version\\\\n# and examining color distribution\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview5.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis: check for red, green, and neutral areas\\\\nred_count = 0\\\\ngreen_count = 0\\\\nneutral_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    # Red dominant\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    # Green dominant\\\\n    elif g > 0.15 and g > r * 1.3 and g > b * 1.3:\\\\n        green_count += 1\\\\n    # Warm (yellow/orange)\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n    # Neutral\\\\n    elif abs(r - g) < 0.05 and abs(g - b) < 0.05:\\\\n        neutral_count += 1\\\\n\\\\nprint(f\\\\\\\"Total visible pixels: {total}\\\\\\\")\\\\nprint(f\\\\\\\"Red dominant: {red_count} ({100*red_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {green_count} ({100*green_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Warm (yellow/orange): {warm_count} ({100*warm_count/total:.1f}%)\\\\\\\")\\\\nprint(f\\\\\\\"Neutral: {neutral_count} ({100*neutral_count/total:.1f}%)\\\\\\\")\\\\n\\\\n# Check if teapot is visible (bright metallic highlights)\\\\nbright_metallic = 0\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    if r > 0.7 and g > 0.65 and b > 0.55:\\\\n        bright_metallic += 1\\\\nprint(f\\\\\\\"\\\\\\\\nBright metallic highlights: {bright_metallic} ({100*bright_metallic/total:.1f}%)\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8805a99244b0b994\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Total visible pixels: 2359296\\\\nRed dominant: 483000 (20.5%)\\\\nGreen dominant: 156 (0.0%)\\\\nWarm (yellow/orange): 1029663 (43.6%)\\\\nNeutral: 88690 (3.8%)\\\\n\\\\nBright metallic highlights: 172218 (7.3%)\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"I see — the green panel isn't showing up well because it's behind the objects. The red cloth is dominant. Let me adjust the green panel to be more visible and improve the Cornell box palette balance.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\n# ============================================================\\\\n# IMPROVE CORNELL BOX PALETTE BALANCE\\\\n# The green needs to be more visible facing the red\\\\n# ============================================================\\\\n\\\\n# Make the green panel larger and more prominent on the right\\\\ngreen_panel = bpy.data.objects[\\\\\\\"GreenPanel\\\\\\\"]\\\\ngreen_panel.location = (2.5, 1.5, 1.8)\\\\ngreen_panel.rotation_euler = (math.radians(90), 0, math.radians(20))\\\\ngreen_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Make the red panel larger too\\\\nred_panel = bpy.data.objects[\\\\\\\"RedPanel\\\\\\\"]\\\\nred_panel.location = (-2.5, 1.5, 1.8)\\\\nred_panel.rotation_euler = (math.radians(90), 0, math.radians(-20))\\\\nred_panel.scale = (3.0, 4.0, 1)\\\\nbpy.ops.object.transform_apply(location=False, rotation=True, scale=True)\\\\n\\\\n# Brighten the green panel material slightly so it reads\\\\nmat_green_panel = bpy.data.materials[\\\\\\\"M_GreenPanel\\\\\\\"]\\\\nnt = mat_green_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.06, 0.28, 0.07, 1.0)  # slightly brighter green\\\\n\\\\n# Also make the red panel slightly brighter\\\\nmat_red_panel = bpy.data.materials[\\\\\\\"M_RedPanel\\\\\\\"]\\\\nnt = mat_red_panel.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.42, 0.06, 0.05, 1.0)  # slightly brighter red\\\\n\\\\n# Make the green velvet cloth brighter too\\\\nmat_green_velvet = bpy.data.materials[\\\\\\\"M_GreenVelvet\\\\\\\"]\\\\nnt = mat_green_velvet.node_tree\\\\nbsdf = nt.nodes['Principled BSDF']\\\\nbsdf.inputs['Base Color'].default_value = (0.07, 0.35, 0.08, 1.0)\\\\n\\\\n# Update the color ramp in green velvet\\\\nfor node in nt.nodes:\\\\n    if node.type == 'VALTORGB':\\\\n        node.color_ramp.elements[0].color = (0.06, 0.32, 0.07, 1.0)\\\\n        node.color_ramp.elements[1].color = (0.10, 0.40, 0.10, 1.0)\\\\n\\\\nprint(\\\\\\\"Cornell palette balanced.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-81b0f5052b6b4974\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Cornell palette balanced.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Quick render to check color balance\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 24\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview6.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Color analysis\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    \\\\n    if brightness < 0.05:\\\\n        continue\\\\n    \\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.12 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red dominant: {100*red_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Green dominant: {100*green_count/total:.1f}%\\\\\\\")\\\\nprint(f\\\\\\\"Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check right side specifically for green\\\\nright_green = 0\\\\nright_total = 0\\\\nfor y in range(h):\\\\n    for x in range(w * 2 // 3, w):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_total += 1\\\\n            if g > 0.1 and g > r * 1.2 and g > b * 1.2:\\\\n                right_green += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_green/right_total:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a4b7c915f2deeb2b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red dominant: 14.0%\\\\nGreen dominant: 3.8%\\\\nWarm: 31.4%\\\\nRight side green: 9.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9f686bd02109d814\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9f686bd02109d814\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The green is now visible. Let me improve the checkered sphere material to be more properly reflective (ray-tracing demo classic), and add a few more refinements. Let me also make the Suzanne bust look more like a proper bust.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad7552f450a30efc\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# ============================================================\\\\n# IMPROVE CHECKERED SPHERE: True ray-tracing reflective chrome\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_CheckeredSphere\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (1000, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (600, 0))\\\\n\\\\n# Perfect mirror chrome with checker pattern\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.02  # very polished, catches reflections\\\\n\\\\n# Checker pattern using texture coordinate\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-400, 0))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-200, 0))\\\\nmapping.inputs['Scale'].default_value = (3.0, 3.0, 3.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nchecker = add_node(nt, 'ShaderNodeTexChecker', (0, 0))\\\\nchecker.inputs['Scale'].default_value = 8.0\\\\nnt.links.new(mapping.outputs['Vector'], checker.inputs['Vector'])\\\\n\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (200, 0))\\\\nnt.links.new(checker.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.02, 0.02, 0.02, 1.0)  # dark squares\\\\ncolor_ramp.color_ramp.elements[1].color = (0.95, 0.95, 0.95, 1.0)  # light squares\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Checkered sphere material improved - true reflective chrome.\\\\\\\")\\\\n\\\\n# ============================================================\\\\n# IMPROVE SUZANNE: Better marble with subsurface scattering feel\\\\n# ============================================================\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\nfor n in list(nt.nodes):\\\\n    nt.nodes.remove(n)\\\\n\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (800, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (400, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.88, 0.85, 0.78, 1.0)  # warm marble\\\\nbsdf.inputs['Roughness'].default_value = 0.25\\\\nbsdf.inputs['Specular IOR Level'].default_value = 0.5\\\\n\\\\n# Marble veining using noise and wave\\\\ntex_coord = add_node(nt, 'ShaderNodeTexCoord', (-600, 100))\\\\nmapping = add_node(nt, 'ShaderNodeMapping', (-400, 100))\\\\nmapping.inputs['Scale'].default_value = (1.0, 3.0, 1.0)\\\\nnt.links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])\\\\n\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (-200, 200))\\\\nnoise.inputs['Scale'].default_value = 3.0\\\\nnoise.inputs['Detail'].default_value = 3.0\\\\nnoise.inputs['Distortion'].default_value = 2.0\\\\nnt.links.new(mapping.outputs['Vector'], noise.inputs['Vector'])\\\\n\\\\nwave = add_node(nt, 'ShaderNodeTexWave', (-200, 100))\\\\nwave.inputs['Scale'].default_value = 3.0\\\\nwave.inputs['Distortion'].default_value = 3.0\\\\nnt.links.new(mapping.outputs['Vector'], wave.inputs['Vector'])\\\\n\\\\nmix = add_node(nt, 'ShaderNodeMix', (0, 100))\\\\nmix.data_type = 'RGBA'\\\\nnt.links.new(wave.outputs['Color'], mix.inputs[6])\\\\nnt.links.new(noise.outputs['Color'], mix.inputs[7])\\\\nnt.links.new(mix.outputs[2], bsdf.inputs['Base Color'])\\\\n\\\\n# Color ramp for veining\\\\nramp = add_node(nt, 'ShaderNodeValToRGB', (200, 100))\\\\nnt.links.new(mix.outputs[2], ramp.inputs['Fac'])\\\\nramp.color_ramp.elements[0].color = (0.85, 0.82, 0.75, 1.0)\\\\nramp.color_ramp.elements[1].color = (0.45, 0.38, 0.30, 1.0)\\\\nnt.links.new(ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\n# Subtle bump\\\\nbump = add_node(nt, 'ShaderNodeBump', (200, -100))\\\\nbump.inputs['Strength'].default_value = 0.08\\\\nnoise3 = add_node(nt, 'ShaderNodeTexNoise', (0, -100))\\\\nnoise3.inputs['Scale'].default_value = 100.0\\\\nnt.links.new(noise3.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Base Color'], bsdf.inputs['Base Color'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nprint(\\\\\\\"Suzanne marble material improved.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad7552f450a30efc\",\"content\":\"{\\n  \\\"status\\\": \\\"error\\\",\\n  \\\"message\\\": \\\"Traceback (most recent call last):\\\\n  File \\\\\\\"C:\\\\\\\\Users\\\\\\\\proud\\\\\\\\Downloads\\\\\\\\Telegram Desktop\\\\\\\\blender-bench-runner-windows\\\\\\\\.runner\\\\\\\\blender-mcp-v1.0.0\\\\\\\\addon\\\\\\\\mcp_to_blender_server.py\\\\\\\", line 230, in _execute_code\\\\n    exec(code, namespace)\\\\n    ~~~~^^^^^^^^^^^^^^^^^\\\\n  File \\\\\\\"<string>\\\\\\\", line 103, in <module>\\\\nKeyError: 'bpy_prop_collection[key]: key \\\\\\\"Base Color\\\\\\\" not found'\\\\n\\\",\\n  \\\"stdout\\\": \\\"Checkered sphere material improved - true reflective chrome.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# The Bump node doesn't have 'Base Color' output - fix Suzanne material\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Remove the bad link\\\\nfor link in list(nt.links):\\\\n    if 'Bump' in link.from_node.name and link.to_socket.name == 'Base Color':\\\\n        nt.links.remove(link)\\\\n        print(f\\\\\\\"Removed bad link from {link.from_node.name}\\\\\\\")\\\\n\\\\n# Verify the material works\\\\nprint(\\\\\\\"Suzanne material nodes:\\\\\\\")\\\\nfor node in nt.nodes:\\\\n    print(f\\\\\\\"  {node.name} ({node.type})\\\\\\\")\\\\n    \\\\nprint(\\\\\\\"\\\\\\\\nLinks:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-88fb07aca4529ea6\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Suzanne material nodes:\\\\n  Material Output (OUTPUT_MATERIAL)\\\\n  Principled BSDF (BSDF_PRINCIPLED)\\\\n  Texture Coordinate (TEX_COORD)\\\\n  Mapping (MAPPING)\\\\n  Noise Texture (TEX_NOISE)\\\\n  Wave Texture (TEX_WAVE)\\\\n  Mix (MIX)\\\\n  Color Ramp (VALTORGB)\\\\n  Bump (BUMP)\\\\n  Noise Texture.001 (TEX_NOISE)\\\\n\\\\nLinks:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9cddced158a16a7f\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Connect bump to BSDF Normal and BSDF to output\\\\nmat = bpy.data.materials.get(\\\\\\\"M_SuzanneMarble\\\\\\\")\\\\nnt = mat.node_tree\\\\n\\\\n# Make sure bump normal goes to BSDF\\\\nbump = None\\\\nbsdf = None\\\\noutput = None\\\\nfor node in nt.nodes:\\\\n    if node.type == 'BUMP':\\\\n        bump = node\\\\n    elif node.type == 'BSDF_PRINCIPLED':\\\\n        bsdf = node\\\\n    elif node.type == 'OUTPUT_MATERIAL':\\\\n        output = node\\\\n\\\\nif bump and bsdf:\\\\n    nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\n    print(\\\\\\\"Connected bump to BSDF Normal\\\\\\\")\\\\n\\\\nif bsdf and output:\\\\n    nt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n    print(\\\\\\\"Connected BSDF to output\\\\\\\")\\\\n\\\\nprint(\\\\\\\"\\\\\\\\nFinal links:\\\\\\\")\\\\nfor link in nt.links:\\\\n    print(f\\\\\\\"  {link.from_node.name}.{link.from_socket.name} -> {link.to_node.name}.{link.to_socket.name}\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9cddced158a16a7f\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Connected bump to BSDF Normal\\\\nConnected BSDF to output\\\\n\\\\nFinal links:\\\\n  Texture Coordinate.Generated -> Mapping.Vector\\\\n  Mapping.Vector -> Noise Texture.Vector\\\\n  Mapping.Vector -> Wave Texture.Vector\\\\n  Wave Texture.Color -> Mix.A\\\\n  Noise Texture.Color -> Mix.B\\\\n  Mix.Result -> Color Ramp.Factor\\\\n  Color Ramp.Color -> Principled BSDF.Base Color\\\\n  Noise Texture.001.Factor -> Bump.Height\\\\n  Bump.Normal -> Principled BSDF.Normal\\\\n  Principled BSDF.BSDF -> Material Output.Surface\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good, Suzanne material is fixed. Now let me render to check everything looks good.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-a1bde82900051568\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.5: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.65: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-a1bde82900051568\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▒ ● ·             |\\\\n  Row 4: |█ ▒ ● ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ █ ▒ ▓ ○ •   |\\\\n  Row 7: |○ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 8: |█ █ █ █ █ █ █ ▒ ▒ ▒ |\\\\n  Row 9: |█ █ █ █ █ █ █ █ ▒ ▒ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-8bf5081c37eebeb6\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-96f3c02259f22638\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Check the right side of the image for green\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview7.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\n# Detailed color check on the right portion\\\\nred_count = 0\\\\ngreen_count = 0\\\\nwarm_count = 0\\\\ntotal = 0\\\\n\\\\nfor i in range(0, len(pixels), 4):\\\\n    r, g, b = pixels[i], pixels[i+1], pixels[i+2]\\\\n    total += 1\\\\n    brightness = (r + g + b) / 3\\\\n    if brightness < 0.05:\\\\n        continue\\\\n    if r > 0.15 and r > g * 1.5 and r > b * 1.5:\\\\n        red_count += 1\\\\n    elif g > 0.1 and g > r * 1.2 and g > b * 1.3:\\\\n        green_count += 1\\\\n    elif r > 0.2 and g > 0.15 and r > b * 1.3:\\\\n        warm_count += 1\\\\n\\\\nprint(f\\\\\\\"Red: {100*red_count/total:.1f}%, Green: {100*green_count/total:.1f}%, Warm: {100*warm_count/total:.1f}%\\\\\\\")\\\\n\\\\n# Check the right side specifically\\\\nright_g = 0\\\\nright_t = 0\\\\nfor y in range(h):\\\\n    for x in range(int(w*0.7), w, 3):\\\\n        idx = (y * w + x) * 4\\\\n        if idx + 2 < len(pixels):\\\\n            r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]\\\\n            right_t += 1\\\\n            if g > 0.08 and g > r * 1.15 and g > b * 1.15:\\\\n                right_g += 1\\\\nprint(f\\\\\\\"Right side green: {100*right_g/right_t:.1f}%\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-96f3c02259f22638\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Red: 14.0%, Green: 3.8%, Warm: 31.4%\\\\nRight side green: 10.8%\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":\"Good - green is now visible on the right side. The composition is taking shape with red on the left, green on the right (Cornell box palette), warm light, and dark shadows. Let me now add some final polish: a candlestick as an additional classical prop (which also justifies the warm light source), and make adjustments to the Suzanne bust positioning.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-99ced8845b19cf57\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport bmesh\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\ndef link_obj(obj):\\\\n    bpy.context.scene.collection.objects.link(obj)\\\\n    return obj\\\\n\\\\n# ============================================================\\\\n# CANDLESTICK with candle - additional classical prop\\\\n# Justifies the warm light source\\\\n# ============================================================\\\\nmesh = bpy.data.meshes.new(\\\\\\\"CandlestickMesh\\\\\\\")\\\\nbm = bmesh.new()\\\\n\\\\n# Profile of the candlestick (radius, height) — lathed\\\\nstick_profile = [\\\\n    (0.00, 0.00),    # center bottom\\\\n    (0.12, 0.00),    # base edge\\\\n    (0.13, 0.01),    # base lip\\\\n    (0.12, 0.03),    # \\\\n    (0.08, 0.04),    # base to stem\\\\n    (0.05, 0.06),    # stem base\\\\n    (0.04, 0.15),    # stem\\\\n    (0.04, 0.25),    # stem\\\\n    (0.05, 0.30),    # mid decorative\\\\n    (0.04, 0.35),    # \\\\n    (0.035, 0.40),   # upper stem\\\\n    (0.05, 0.44),    # candle cup base\\\\n    (0.06, 0.46),    # cup\\\\n    (0.055, 0.48),   # cup lip\\\\n    (0.04, 0.50),    # cup inner\\\\n    (0.00, 0.50),    # center top\\\\n]\\\\n\\\\nsegments = 48\\\\nall_verts = []\\\\nfor r, h in stick_profile:\\\\n    ring = []\\\\n    if r < 0.001:\\\\n        v = bm.verts.new((0, 0, h))\\\\n        ring = [v] * segments\\\\n    else:\\\\n        for i in range(segments):\\\\n            angle = (i / segments) * math.tau\\\\n            x = r * math.cos(angle)\\\\n            y = r * math.sin(angle)\\\\n            v = bm.verts.new((x, y, h))\\\\n            ring.append(v)\\\\n    all_verts.append(ring)\\\\n\\\\nbm.verts.ensure_lookup_table()\\\\n\\\\nfor ri in range(len(all_verts) - 1):\\\\n    ring_a = all_verts[ri]\\\\n    ring_b = all_verts[ri + 1]\\\\n    ra, _ = stick_profile[ri]\\\\n    rb, _ = stick_profile[ri + 1]\\\\n    for i in range(segments):\\\\n        j = (i + 1) % segments\\\\n        if ra < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j]])\\\\n        elif rb < 0.001:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_a[j]])\\\\n        else:\\\\n            bm.faces.new([ring_a[i], ring_b[i], ring_b[j], ring_a[j]])\\\\n\\\\nbm.normal_update()\\\\nbm.to_mesh(mesh)\\\\nbm.free()\\\\n\\\\nstick_obj = bpy.data.objects.new(\\\\\\\"Candlestick\\\\\\\", mesh)\\\\nlink_obj(stick_obj)\\\\nstick_obj.location = (-1.6, 0.8, 0.0)\\\\nbpy.context.view_layer.objects.active = stick_obj\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nmod = stick_obj.modifiers.new(\\\\\\\"Subsurf\\\\\\\", 'SUBSURF')\\\\nmod.levels = 1\\\\nmod.render_levels = 2\\\\n\\\\n# Candle\\\\nbpy.ops.mesh.primitive_cylinder_add(radius=0.035, depth=0.15, location=(-1.6, 0.8, 0.575))\\\\ncandle = bpy.context.active_object\\\\ncandle.name = \\\\\\\"Candle\\\\\\\"\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\n# Candle flame - a small emissive shape\\\\nbpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, segments=16, ring_count=8, location=(-1.6, 0.8, 0.70))\\\\nflame = bpy.context.active_object\\\\nflame.name = \\\\\\\"CandleFlame\\\\\\\"\\\\nflame.scale = (0.6, 0.6, 1.8)\\\\nbpy.ops.object.transform_apply(location=False, rotation=False, scale=True)\\\\nbpy.ops.object.shade_smooth()\\\\n\\\\nprint(\\\\\\\"Candlestick with candle and flame built.\\\\\\\")\\\\nresult = {\\\\\\\"candlestick\\\\\\\": stick_obj.name, \\\\\\\"candle\\\\\\\": candle.name, \\\\\\\"flame\\\\\\\": flame.name}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-99ced8845b19cf57\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"candlestick\\\": \\\"Candlestick\\\",\\n    \\\"candle\\\": \\\"Candle\\\",\\n    \\\"flame\\\": \\\"CandleFlame\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick with candle and flame built.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-86253733bb060d5b\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\n\\\\ndef create_material(name):\\\\n    mat = bpy.data.materials.new(name)\\\\n    mat.use_nodes = True\\\\n    nt = mat.node_tree\\\\n    for n in list(nt.nodes):\\\\n        nt.nodes.remove(n)\\\\n    return mat, nt\\\\n\\\\ndef add_node(nt, node_type, location=(0,0)):\\\\n    n = nt.nodes.new(node_type)\\\\n    n.location = location\\\\n    return n\\\\n\\\\n# --- Candlestick: Aged brass/bronze ---\\\\nmat, nt = create_material(\\\\\\\"M_CandlestickBrass\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (600, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (300, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.55, 0.42, 0.20, 1.0)  # brass\\\\nbsdf.inputs['Metallic'].default_value = 1.0\\\\nbsdf.inputs['Roughness'].default_value = 0.35\\\\n\\\\n# Patina variation\\\\nnoise = add_node(nt, 'ShaderNodeTexNoise', (0, 100))\\\\nnoise.inputs['Scale'].default_value = 5.0\\\\nnoise.inputs['Detail'].default_value = 4.0\\\\ncolor_ramp = add_node(nt, 'ShaderNodeValToRGB', (100, 100))\\\\nnt.links.new(noise.outputs['Fac'], color_ramp.inputs['Fac'])\\\\ncolor_ramp.color_ramp.elements[0].color = (0.55, 0.42, 0.20, 1.0)  # brass\\\\ncolor_ramp.color_ramp.elements[1].color = (0.25, 0.35, 0.20, 1.0)  # patina\\\\nnt.links.new(color_ramp.outputs['Color'], bsdf.inputs['Base Color'])\\\\n\\\\nbump = add_node(nt, 'ShaderNodeBump', (100, -100))\\\\nbump.inputs['Strength'].default_value = 0.2\\\\nnoise2 = add_node(nt, 'ShaderNodeTexNoise', (-100, -100))\\\\nnoise2.inputs['Scale'].default_value = 40.0\\\\nnt.links.new(noise2.outputs['Fac'], bump.inputs['Height'])\\\\nnt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\n\\\\nbpy.data.objects[\\\\\\\"Candlestick\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle: Waxed off-white ---\\\\nmat, nt = create_material(\\\\\\\"M_Candle\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nbsdf = add_node(nt, 'ShaderNodeBsdfPrincipled', (200, 0))\\\\nbsdf.inputs['Base Color'].default_value = (0.85, 0.82, 0.72, 1.0)\\\\nbsdf.inputs['Roughness'].default_value = 0.5\\\\nnt.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"Candle\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# --- Candle flame: Emissive ---\\\\nmat, nt = create_material(\\\\\\\"M_CandleFlame\\\\\\\")\\\\noutput = add_node(nt, 'ShaderNodeOutputMaterial', (400, 0))\\\\nemission = add_node(nt, 'ShaderNodeEmission', (200, 0))\\\\nemission.inputs['Color'].default_value = (1.0, 0.7, 0.3, 1.0)  # warm flame\\\\nemission.inputs['Strength'].default_value = 15.0\\\\nnt.links.new(emission.outputs['Emission'], output.inputs['Surface'])\\\\nbpy.data.objects[\\\\\\\"CandleFlame\\\\\\\"].data.materials.append(mat)\\\\n\\\\n# Add a point light at the flame for actual illumination\\\\nbpy.ops.object.light_add(type='POINT', location=(-1.6, 0.8, 0.72))\\\\nflame_light = bpy.context.active_object\\\\nflame_light.name = \\\\\\\"CandleLight\\\\\\\"\\\\nflame_light.data.energy = 50\\\\nflame_light.data.color = (1.0, 0.7, 0.3)\\\\nflame_light.data.shadow_soft_size = 0.05\\\\n\\\\nprint(\\\\\\\"Candlestick, candle, and flame materials created.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-86253733bb060d5b\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Candlestick, candle, and flame materials created.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ad276f7e043b8f86\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render with candle\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview8.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview8.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (10x10 grid):\\\\\\\")\\\\nfor gy in range(10):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(10):\\\\n        x1 = gx * w // 10\\\\n        x2 = (gx+1) * w // 10\\\\n        y1 = gy * h // 10\\\\n        y2 = (gy+1) * h // 10\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 25):\\\\n            for x in range(x1, x2, 25):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ad276f7e043b8f86\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (10x10 grid):\\\\n  Row 0: |  · ·         · · · |\\\\n  Row 1: |• ·     · • • · ·   |\\\\n  Row 2: |· • ○ • ·           |\\\\n  Row 3: |▓ ▓ ● ·             |\\\\n  Row 4: |▒ ▒ ▓ ·             |\\\\n  Row 5: |▓ ● ▓ ● ● ·         |\\\\n  Row 6: |  ● ▒ ▒ ▒ ▓ ▓ ○ •   |\\\\n  Row 7: |● █ █ █ ▒ ▒ ▒ ▒ ▓ ▓ |\\\\n  Row 8: |█ █ █ █ █ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 9: |▒ █ █ █ █ █ █ ▒ ▒ ▓ |\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-ac68c75cb6cd7431\",\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"arguments\":\"{\\\"area_ui_type\\\": \\\"VIEW_3D\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-ac68c75cb6cd7431\",\"content\":\"\"},{\"role\":\"assistant\",\"content\":\"The composition is looking good. Let me make some final adjustments: I want to ensure the table edge is visible in the lower frame, and that the objects are well-grouped with overlapping depth. Let me also add a few more details to sell the Dutch Golden Age look.\",\"tool_calls\":[{\"id\":\"chatcmpl-tool-880e723bea6f81d2\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\nimport math\\\\nfrom mathutils import Vector\\\\n\\\\n# ============================================================\\\\n# FINAL COMPOSITION ADJUSTMENTS\\\\n# ============================================================\\\\n\\\\n# Adjust camera to see table edge in lower frame and get better angle\\\\ncam = bpy.data.objects[\\\\\\\"Camera_Presentation\\\\\\\"]\\\\ncam.location = (3.0, -3.5, 1.8)\\\\ntarget = Vector((0.1, -0.1, 0.3))\\\\ndirection = target - cam.location\\\\nrot_quat = direction.to_track_quat('-Z', 'Y')\\\\ncam.rotation_euler = rot_quat.to_euler()\\\\ncam.data.dof.focus_distance = (cam.location - target).length\\\\n\\\\n# Adjust teapot position to be more centered and commanding\\\\nteapot = bpy.data.objects[\\\\\\\"UtahTeapot\\\\\\\"]\\\\nteapot.location = (0.0, 0.0, 0.0)\\\\nteapot.rotation_euler = (0, 0, math.radians(-15))\\\\nteapot.scale = (0.95, 0.95, 0.95)\\\\n\\\\n# Bunny slightly closer and turned toward camera\\\\nbunny = bpy.data.objects[\\\\\\\"StanfordBunny\\\\\\\"]\\\\nbunny.location = (-1.0, 0.2, 0.03)\\\\nbunny.rotation_euler = (0, math.radians(5), math.radians(30))\\\\nbunny.scale = (1.15, 1.15, 1.15)\\\\n\\\\n# Suzanne on right, gazing out\\\\nsuzanne = bpy.data.objects[\\\\\\\"Suzanne\\\\\\\"]\\\\nsuzanne.location = (1.0, -0.1, 0.2)\\\\nsuzanne.rotation_euler = (math.radians(8), math.radians(-5), math.radians(70))\\\\nbase = bpy.data.objects[\\\\\\\"SuzanneBase\\\\\\\"]\\\\nbase.location = (suzanne.location.x, suzanne.location.y, 0.04)\\\\n\\\\n# Sphere more centered, in front of teapot\\\\nsphere = bpy.data.objects[\\\\\\\"CheckeredSphere\\\\\\\"]\\\\nsphere.location = (0.2, -0.65, 0.22)\\\\n\\\\n# Wine glass moved slightly\\\\nglass = bpy.data.objects[\\\\\\\"WineGlass\\\\\\\"]\\\\nglass.location = (1.65, 0.4, 0.0)\\\\nwine = bpy.data.objects[\\\\\\\"WineLiquid\\\\\\\"]\\\\nwine.location = glass.location.copy()\\\\n\\\\n# Candlestick on left, behind bunny\\\\nstick = bpy.data.objects[\\\\\\\"Candlestick\\\\\\\"]\\\\nstick.location = (-1.7, 0.9, 0.0)\\\\ncandle = bpy.data.objects[\\\\\\\"Candle\\\\\\\"]\\\\ncandle.location = (-1.7, 0.9, 0.575)\\\\nflame = bpy.data.objects[\\\\\\\"CandleFlame\\\\\\\"]\\\\nflame.location = (-1.7, 0.9, 0.70)\\\\nflame_light = bpy.data.objects[\\\\\\\"CandleLight\\\\\\\"]\\\\nflame_light.location = (-1.7, 0.9, 0.72)\\\\n\\\\n# Book\\\\nbook = bpy.data.objects[\\\\\\\"OpenBook\\\\\\\"]\\\\nbook.location = (-0.4, -0.85, 0.02)\\\\nbook.rotation_euler = (0, 0, math.radians(25))\\\\ncover = bpy.data.objects[\\\\\\\"BookCover\\\\\\\"]\\\\ncover.location = book.location.copy()\\\\ncover.rotation_euler = book.rotation_euler.copy()\\\\n\\\\n# Fruit\\\\nbpy.data.objects[\\\\\\\"Orange1\\\\\\\"].location = (0.8, -0.85, 0.09)\\\\nbpy.data.objects[\\\\\\\"Orange2\\\\\\\"].location = (1.0, -0.75, 0.075)\\\\nbpy.data.objects[\\\\\\\"Lemon1\\\\\\\"].location = (0.65, -0.7, 0.08)\\\\n\\\\nprint(\\\\\\\"Final composition adjustments made.\\\\\\\")\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-880e723bea6f81d2\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Final composition adjustments made.\\\\n\\\"\\n}\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-9ab206cfd8c4ba5d\",\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"arguments\":\"{\\\"code\\\": \\\"\\\\nimport bpy\\\\n\\\\n# Render preview\\\\nscene = bpy.context.scene\\\\nscene.cycles.samples = 32\\\\nscene.render.filepath = \\\\\\\"C:/tmp/still_life_preview9.png\\\\\\\"\\\\nbpy.ops.render.render(write_still=True)\\\\n\\\\nimg = bpy.data.images.load(\\\\\\\"C:/tmp/still_life_preview9.png\\\\\\\")\\\\nw, h = img.size[0], img.size[1]\\\\npixels = list(img.pixels)\\\\n\\\\nprint(\\\\\\\"Brightness map (12x12 grid):\\\\\\\")\\\\nfor gy in range(12):\\\\n    row = \\\\\\\"\\\\\\\"\\\\n    for gx in range(12):\\\\n        x1 = gx * w // 12\\\\n        x2 = (gx+1) * w // 12\\\\n        y1 = gy * h // 12\\\\n        y2 = (gy+1) * h // 12\\\\n        bright_sum = 0\\\\n        count = 0\\\\n        for y in range(y1, y2, 30):\\\\n            for x in range(x1, x2, 30):\\\\n                idx = (y * w + x) * 4\\\\n                if idx + 2 < len(pixels):\\\\n                    bright_sum += (pixels[idx] + pixels[idx+1] + pixels[idx+2]) / 3\\\\n                    count += 1\\\\n        bright = bright_sum / count if count > 0 else 0\\\\n        if bright < 0.06: row += \\\\\\\"  \\\\\\\"\\\\n        elif bright < 0.12: row += \\\\\\\"· \\\\\\\"\\\\n        elif bright < 0.2: row += \\\\\\\"• \\\\\\\"\\\\n        elif bright < 0.3: row += \\\\\\\"○ \\\\\\\"\\\\n        elif bright < 0.4: row += \\\\\\\"● \\\\\\\"\\\\n        elif bright < 0.55: row += \\\\\\\"▓ \\\\\\\"\\\\n        elif bright < 0.7: row += \\\\\\\"▒ \\\\\\\"\\\\n        else: row += \\\\\\\"█ \\\\\\\"\\\\n    print(f\\\\\\\"  Row {gy}: |{row}|\\\\\\\")\\\\n\\\\nresult = {\\\\\\\"status\\\\\\\": \\\\\\\"ok\\\\\\\"}\\\\n\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"chatcmpl-tool-9ab206cfd8c4ba5d\",\"content\":\"{\\n  \\\"status\\\": \\\"ok\\\",\\n  \\\"result\\\": {\\n    \\\"status\\\": \\\"ok\\\"\\n  },\\n  \\\"stdout\\\": \\\"Brightness map (12x12 grid):\\\\n  Row 0: |· ·       · • • • • ·   |\\\\n  Row 1: |•     • ○ ○ • ·         |\\\\n  Row 2: |  • ● ○ • ·             |\\\\n  Row 3: |▓ ▓ ○                   |\\\\n  Row 4: |▒ ▒ ● •                 |\\\\n  Row 5: |▒ ▒ ▓ · ·               |\\\\n  Row 6: |▒ ▓ ● ○ •               |\\\\n  Row 7: |○ ● ▒ ▓ █ ▒ ● • ·       |\\\\n  Row 8: |  ▒ ▒ ▒ ▒ ▒ ▓ ▒ ▓ ● ○ · |\\\\n  Row 9: |▓ █ █ █ █ ▒ ▒ ▒ ▒ ▒ ▒ ▓ |\\\\n  Row 10: |█ █ █ █ █ █ ▒ ▒ ▒ ▒ ▒ ▒ |\\\\n  Row 11: |█ █ █ █ █ █ █ █ █ ▒ ▒ ▒ |\\\\n\\\"\\n}\"}],\"usage\":{\"include\":true},\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code\",\"description\":\"\\n        Execute Python code in the connected Blender instance.\\n\\n        The code runs in Blender's Python environment with full access to ``bpy``.\\n        To return data, assign a JSON-serialisable dict to a variable named ``result``.\\n        Deferred completion via ``check_is_finished`` is only supported by the\\n        interactive addon server, and is rejected in background mode.\\n        \",\"parameters\":{\"properties\":{\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"code\"],\"title\":\"execute_blender_codeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"execute_blender_code_for_cli\",\"description\":\"\\n        Execute Python code in a background Blender process.\\n\\n        Opens *blend_file* with ``blender --background`` and runs *code*.\\n        Assign a dict to ``result`` to return data.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"},\"code\":{\"title\":\"Code\",\"type\":\"string\"}},\"required\":[\"blend_file\",\"code\"],\"title\":\"execute_blender_code_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks\",\"description\":\"\\n        Return a summary of the blend file: data-block counts, active workspace, and render engine.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_datablocksArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_datablocks_for_cli\",\"description\":\"\\n        Return a data-block summary by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_datablocks_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files\",\"description\":\"\\n        Report external file references that are missing from disk\\n        (images, libraries, fonts, sounds, movie clips, caches, sequences).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_missing_filesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_missing_files_for_cli\",\"description\":\"\\n        Report missing file references by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_missing_files_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries\",\"description\":\"\\n        Return a tree of directly and indirectly linked library files.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_of_linked_librariesArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_of_linked_libraries_for_cli\",\"description\":\"\\n        Return linked-library info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_of_linked_libraries_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info\",\"description\":\"\\n        Simple/fast access to the blend file's path, save status, age, and backups.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_path_infoArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_path_info_for_cli\",\"description\":\"\\n        Return path info by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_path_info_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess\",\"description\":\"\\n        Guess the primary use-cases of the current blend file (scored 0-100 with certainty).\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_blendfile_summary_usage_guessArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_blendfile_summary_usage_guess_for_cli\",\"description\":\"\\n        Guess use-cases by opening *blend_file* in background Blender.\\n        \",\"parameters\":{\"properties\":{\"blend_file\":{\"title\":\"Blend File\",\"type\":\"string\"}},\"required\":[\"blend_file\"],\"title\":\"get_blendfile_summary_usage_guess_for_cliArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_object_detail_summary\",\"description\":\"\\n        Return a structured summary of the object identified by *name*.\\n\\n        Includes type, transforms, parent, children, modifiers, constraints,\\n        materials, visibility, data-block name, and collections.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"get_object_detail_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_objects_summary\",\"description\":\"\\n        Return the scene's collection hierarchy and their objects.\\n\\n        Each collection lists its objects (name, type, parent, data name,\\n        selection, visibility) and nested child collections.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_objects_summaryArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_python_api_docs\",\"description\":\"\\n        Return the Blender Python API docs for *identifier*, or list\\n        modules matching a trailing-``*`` discovery pattern.\\n\\n        *identifier* should be a fully-qualified Python name (e.g.\\n        ``bpy.app`` or ``bpy.types.Scene.frame_current``).\\n        The trailing-``*`` forms are supported as discovery entry-points:\\n\\n        - ``*`` enumerates the top-level modules (``bpy``, ``bmesh``,\\n          ``mathutils``, ``gpu``, ...).\\n        - ``X.*`` enumerates the direct-child identifiers under the\\n          *X* namespace (``bpy.*`` -> ``bpy.app``, ``bpy.context``, ...).\\n\\n        Both return a ``namespace`` response even when ``X.rst`` would\\n        otherwise resolve to ``exact``; the ``.*`` form lets an agent\\n        force the child listing.\\n\\n        The response always carries ``kind``, ``found``, and ``identifier``.\\n        The remaining keys depend on ``kind``:\\n\\n        - ``\\\"exact\\\"`` (``found=True``): ``<identifier>.rst`` was read.\\n          Extra keys: ``content`` (RST text), ``examples``. When the\\n          file exceeds 32 KB, ``content`` is replaced with a dot-point\\n          summary of the file's top-level definitions (prefixed by a\\n          header noting the truncation) and ``examples`` is empty -\\n          re-query individual members for their rendered blocks.\\n        - ``\\\"namespace\\\"`` (``found=True``):\\n          no ``<identifier>.rst`` but ``<identifier>.<child>.rst`` siblings exist.\\n          Extra key: ``submodules`` (list of child identifiers).\\n        - ``\\\"definition\\\"`` (``found=True``):\\n          *identifier* is defined inside a parent RST\\n          (e.g. ``bpy.props.IntProperty`` lives in ``bpy.props.rst``).\\n          Extra keys: ``content`` (rendered block), ``examples``.\\n        - ``\\\"partial\\\"`` (``found=False``):\\n          the parent RST was located but the trailing component isn't defined in it.\\n          Extra keys:\\n          - ``parent`` the identifier whose RST was loaded.\\n          - ``available`` top-level definitions in that RST.\\n          - ``submodules`` sibling identifiers ``<parent>.<child>`` with their own RSTs,\\n            filtered to those whose last component contains every character of the missing tail.\\n\\n          For a toctree landing page like ``bpy.types`` ``available`` is empty and ``submodules``\\n          is the near-miss list; for a self-contained module like ``bpy.props`` it's the reverse.\\n        - ``\\\"suggestions\\\"`` (``found=False``):\\n          no direct match, but *identifier* appears as a component of other files.\\n          Extra key: ``suggestions`` (list of full identifiers).\\n        - ``\\\"missing\\\"`` (``found=False``): nothing matched.\\n\\n        ``examples`` (present on the ``exact`` and ``definition`` kinds)\\n        is a list of ``{path, content}`` entries referenced from this documentation.\\n        \",\"parameters\":{\"properties\":{\"identifier\":{\"title\":\"Identifier\",\"type\":\"string\"}},\"required\":[\"identifier\"],\"title\":\"get_python_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_area_as_image\",\"description\":\"\\n        Take a screenshot of a single Blender area and return it as a PNG image.\\n\\n        *area_ui_type* matches the area's ``ui_type``.\\n\\n        *size_limit_in_bytes* caps the image size in bytes.\\n        Zero (the default) uses the MCP message size limit.\\n        \",\"parameters\":{\"properties\":{\"area_ui_type\":{\"enum\":[\"VIEW_3D\",\"IMAGE_EDITOR\",\"UV\",\"ShaderNodeTree\",\"CompositorNodeTree\",\"GeometryNodeTree\",\"TextureNodeTree\",\"SEQUENCE_EDITOR\",\"CLIP_EDITOR\",\"DOPESHEET_EDITOR\",\"GRAPH_EDITOR\",\"NLA_EDITOR\",\"TEXT_EDITOR\",\"CONSOLE\",\"INFO\",\"TOPBAR\",\"STATUSBAR\",\"OUTLINER\",\"PROPERTIES\",\"FILE_BROWSER\",\"SPREADSHEET\",\"PREFERENCES\"],\"title\":\"Area Ui Type\",\"type\":\"string\"},\"size_limit_in_bytes\":{\"default\":0,\"title\":\"Size Limit In Bytes\",\"type\":\"integer\"}},\"required\":[\"area_ui_type\"],\"title\":\"get_screenshot_of_area_as_imageArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"get_screenshot_of_window_as_json\",\"description\":\"\\n        Return a JSON description of the Blender window layout, areas, active object, and selection.\\n        \",\"parameters\":{\"properties\":{},\"title\":\"get_screenshot_of_window_as_jsonArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_name\",\"description\":\"\\n        Switch the active workspace tab to *name*.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"}},\"required\":[\"name\"],\"title\":\"jump_to_tab_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_tab_by_space_type\",\"description\":\"\\n        Switch to a workspace whose main area matches *space_type*.\\n\\n        If *allow_edits* is True and no matching workspace exists, a new one\\n        is created by duplicating the current workspace.\\n        \",\"parameters\":{\"properties\":{\"space_type\":{\"title\":\"Space Type\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"space_type\"],\"title\":\"jump_to_tab_by_space_typeArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_by_name\",\"description\":\"\\n        Move the 3D viewport to focus on an object by *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"jump_to_view3d_object_data_by_name\",\"description\":\"\\n        Move the 3D viewport to the object whose data block matches *name*.\\n\\n        If *allow_edits* is True the object may be un-hidden and its\\n        collections enabled to make it visible.\\n        \",\"parameters\":{\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\"},\"allow_edits\":{\"default\":false,\"title\":\"Allow Edits\",\"type\":\"boolean\"}},\"required\":[\"name\"],\"title\":\"jump_to_view3d_object_data_by_nameArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_thumbnail_to_path\",\"description\":\"\\n        Render a small, low-quality thumbnail to *output_path* (temporarily overrides settings).\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_thumbnail_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"render_viewport_to_path\",\"description\":\"\\n        Render the current scene to *output_path* using current render settings.\\n        \",\"parameters\":{\"properties\":{\"output_path\":{\"title\":\"Output Path\",\"type\":\"string\"}},\"required\":[\"output_path\"],\"title\":\"render_viewport_to_pathArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_api_docs\",\"description\":\"\\nFull-text search over the bundled Blender Python API reference.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_api_docsArguments\",\"type\":\"object\"}}},{\"type\":\"function\",\"function\":{\"name\":\"search_manual_docs\",\"description\":\"\\nFull-text search over the bundled Blender user manual.\\n\\nReturns a ranked list of hits. Each hit has:\\n\\n- ``path``: file path relative to the bundled docs.\\n- ``text``: the matching paragraph plus ``context``\\n  paragraphs on either side.\\n- ``breadcrumb``: the section path containing the hit\\n  (``Section > Sub-section > ...``).\\n- ``index``: the hit's position in the result list.\\n- ``score``: a relevance score; higher is better.\\n\\nThe query is tokenised on whitespace and matched\\ncase-insensitively. Every token must appear somewhere in\\nthe paragraph body, the file path, or an enclosing section\\ntitle - in any order. Common English stop-words (``the``,\\n``a``, ``how``, ``to``, ...) are dropped, so natural\\nphrasings like ``\\\"how to bake\\\"`` work as expected. Regular\\nexpressions are not supported.\\n\\nUse ``context`` to pull more surrounding paragraphs into\\neach hit (symmetric, default 0). Use ``index`` with the\\nposition of a previous hit (same query) to get that hit\\nalone with its text widened to its enclosing section.\\n\\nRead-only; consults bundled RST files only.\\n\",\"parameters\":{\"properties\":{\"query\":{\"title\":\"Query\",\"type\":\"string\"},\"max_results\":{\"default\":20,\"title\":\"Max Results\",\"type\":\"integer\"},\"context\":{\"default\":0,\"title\":\"Context\",\"type\":\"integer\"},\"index\":{\"anyOf\":[{\"type\":\"integer\"},{\"type\":\"null\"}],\"default\":null,\"title\":\"Index\"}},\"required\":[\"query\"],\"title\":\"search_manual_docsArguments\",\"type\":\"object\"}}}]}", "body_base64": "eyJtb2RlbCI6InotYWkvZ2xtLTUuMiIsIm1lc3NhZ2VzIjpbeyJyb2xlIjoic3lzdGVtIiwiY29udGVudCI6IllvdSBhcmUgcGFydGljaXBhdGluZyBpbiBCbGVuZGVyLUJlbmNoLCBhIHB1YmxpYyBiZW5jaG1hcmsgd2hlcmUgQUkgbW9kZWxzIGNvbXBsZXRlIHRoZSBzYW1lIEJsZW5kZXIgdGFzay5cblxuWW91ciByZXN1bHQgd2lsbCBiZSBjb21wYXJlZCBoZWFkLXRvLWhlYWQgd2l0aCBhbm90aGVyIG1vZGVsLiBBbnlvbmUgb24gdGhlIGludGVybmV0IGNhbiB2b3RlIGJhc2VkIG9uIHR3byBlcXVhbGx5IGltcG9ydGFudCBwdWJsaXNoZWQgdmlld3M6IGEgMkQgcmVuZGVyZWQgcHJlc2VudGF0aW9uIGFuZCBhbiBpbnRlcmFjdGl2ZSAzRCBzY2VuZSBleHBvcnRlZCB0byBHTEIuIFRyZWF0IG5laXRoZXIgdmlldyBhcyBvcHRpb25hbDsgbWFrZSB0aGUgcmVzdWx0IGNsZWFyIGFuZCBjb21wZWxsaW5nIGluIGJvdGguXG5cbkNvbXBsZXRlIHRoZSByZXF1ZXN0IGFzIHdlbGwgYXMgeW91IGNhbi4gVGhlIGJlbmNobWFyayBkb2VzIG5vdCBwcmVzY3JpYmUgYSB3b3JrZmxvdyBvciB2aXN1YWwgc3R5bGU7IHVzZSB3aGljaGV2ZXIgQmxlbmRlciB0ZWNobmlxdWVzIHlvdSBjb25zaWRlciBhcHByb3ByaWF0ZS4gTWFrZSB0aGUgaW1wb3J0YW50IHJlcXVpcmVtZW50cyBldmlkZW50IGluIHRoZSBwdWJsaXNoZWQgcmVzdWx0LCBzYXZlIGEgY29tcGxldGUgc2NlbmUsIGFuZCBwcmVzZW50IHRoZSB3b3JrIGNsZWFybHkgaW4gZXZlcnkgcmVxdWVzdGVkIG91dHB1dC5cblxuVGhlIDJEIHByZXNlbnRhdGlvbiBpcyByZW5kZXJlZCBieSB0aGUgYmVuY2htYXJrIGZyb20geW91ciBzYXZlZCBzY2VuZSB1c2luZyBDeWNsZXMgYXQgMTUzNiB4IDE1MzYsIDY0IHNhbXBsZXMsIGRlbm9pc2luZyBlbmFibGVkLCBhbmQgR1BVIGFjY2VsZXJhdGlvbiB3aGVuIGF2YWlsYWJsZSB3aXRoIGEgQ1BVIGZhbGxiYWNrLiBJdCBpcyB0aGUgbmF0aXZlLWZpZGVsaXR5IHZpZXcgb2YgdGhlIEJsZW5kZXIgc2NlbmUsIHNvIHlvdSBtYXkgdXNlIEJsZW5kZXIncyBmdWxsIGZlYXR1cmUgc2V0LiBQcmV2aWV3IGFuZCB2YWxpZGF0ZSB5b3VyIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjYW1lcmEgY29tcG9zaXRpb24gaW4gQ3ljbGVzLCBhbmQgZG8gbm90IHJlbHkgb24gRUVWRUUtb25seSBlZmZlY3RzIGZvciB0aGUgZmluYWwgYXBwZWFyYW5jZS5cblxuVGhlIGludGVyYWN0aXZlIDNEIHZpZXcgaXMgYSBiZXN0LWVmZm9ydCBHTEIgZXhwb3J0IGNvbnRhaW5pbmcgZ2VvbWV0cnksIGNvbXBhdGlibGUgbWF0ZXJpYWxzLCB0aGUgY29udGVzdGFudCBjYW1lcmEsIGFuZCBzdXBwb3J0ZWQgbGlnaHRzLiBCZWNhdXNlIGdsVEYgY2Fubm90IHJlcHJlc2VudCBldmVyeSBCbGVuZGVyIGZlYXR1cmUsIG5hdGl2ZSBlZmZlY3RzIHN1Y2ggYXMgcGFydGljbGVzLCBoYWlyIG9yIGN1cnZlcywgdm9sdW1lcywgc2ltdWxhdGlvbnMsIGFuZCBzb21lIHByb2NlZHVyYWwgZ2VvbWV0cnkgbWF5IGFwcGVhciBvbmx5IGluIHRoZSAyRCByZW5kZXIuIFRoZSBiZW5jaG1hcmsgbWF5IGFsc28gZ2VuZXJhdGUgYSBzZXBhcmF0ZSBwcmV2aWV3IEdMQiBieSBiYWtpbmcgc3VwcG9ydGVkIHByb2NlZHVyYWwgbWF0ZXJpYWwgaW5wdXRzIHRvIHRleHR1cmVzOyB0aGlzIGRvZXMgbm90IGNvbnZlcnQgdW5zdXBwb3J0ZWQgZ2VvbWV0cnkgb3IgZ3VhcmFudGVlIGV4YWN0IHBhcml0eSB3aXRoIEJsZW5kZXIuIFdoZW4gcHJhY3RpY2FsLCBrZWVwIHRoZSBjb3JlIGZvcm0gYW5kIHNjZW5lIHJlYWRhYmxlIGluIHRoZSAzRCB2aWV3IHdoaWxlIHVzaW5nIHRoZSAyRCBwcmVzZW50YXRpb24gdG8gc2hvdyBuYXRpdmUgQmxlbmRlciBmZWF0dXJlcyBmYWl0aGZ1bGx5LlxuXG4jIyBIYXJuZXNzIEluc3RydWN0aW9uc1xuXG5Zb3UgYXJlIG9wZXJhdGluZyBCbGVuZGVyIHRocm91Z2ggdGhlIHByb3ZpZGVkIHRvb2xzLiBUb29sIGNhbGxzIGV4ZWN1dGUgb25lIGF0IGEgdGltZSwgaW4gdGhlIG9yZGVyIHlvdSBpc3N1ZSB0aGVtLCBhZ2FpbnN0IGEgc2luZ2xlIGxpdmUgQmxlbmRlciBpbnN0YW5jZSDigJQgZWFjaCBjYWxsIHNlZXMgdGhlIHN0YXRlIGxlZnQgYnkgdGhlIHByZXZpb3VzIG9uZSwgYW5kIGlzc3Vpbmcgc2V2ZXJhbCBjYWxscyBpbiBvbmUgbWVzc2FnZSBnYWlucyBubyBwYXJhbGxlbGlzbS4gVGhlIHNjZW5lIHN0YXJ0cyBlbXB0eS4gQnVpbGQgd2hhdCB0aGUgdXNlcidzIHByb21wdCBhc2tzIGZvciBpbiB0aGUgY3VycmVudCBzY2VuZS4gV29yayBzdGVwIGJ5IHN0ZXAgYW5kIHZlcmlmeSB5b3VyIG93biB3b3JrLlxuXG5Zb3UgYXJlIGJ1aWxkaW5nIGEgcmVhbCB0aHJlZS1kaW1lbnNpb25hbCBzY2VuZSwgYW5kIGV2YWx1YXRvcnMganVkZ2UgdGhlIHdob2xlIHNjZW5lIGFuZCB5b3VyIGZpbmFsIHJlbmRlciBzaWRlIGJ5IHNpZGUg4oCUIGFuIGludGVyYWN0aXZlIDNEIHZpZXcgYW5kIGEgYmVuY2htYXJrLWdlbmVyYXRlZCAzNjDCsCBjYW1lcmEgb3JiaXQgcmVuZGVyZWQgaW4gQ3ljbGVzIGZyb20geW91ciBzYXZlZCBzY2VuZSBhcHBlYXIgbmV4dCB0byB5b3VyIHByZXNlbnRhdGlvbiByZW5kZXIsIHNvIGZvcm1zIHRoYXQgb25seSByZWFkIGNvcnJlY3RseSBmcm9tIG9uZSBhbmdsZSB3aWxsIHNob3cuIEJ1aWxkIGdlbnVpbmUgM0QgZmlyc3QsIHRoZW4gcHJlc2VudCBpdCB3ZWxsOiBiZWZvcmUgeW91IGZpbmlzaCwgc2V0IHVwIGEgY2FtZXJhIGFuZCBsaWdodGluZyB0byBmcmFtZSBhIHNpbmdsZSwgd2VsbC1jb21wb3NlZCBwcmVzZW50YXRpb24gaW1hZ2Ugb2YgeW91ciByZXN1bHQg4oCUIGEgZ29vZCBzY2VuZSB0aGF0IGhhcHBlbnMgdG8gaGF2ZSBhIHdlbGwtcGxhY2VkIGNhbWVyYSBhbmQgbGlnaHRzLiBUaGUgZmluYWwgYmVuY2htYXJrIGNhcHR1cmUgb3ZlcnJpZGVzIHRoZSBzY2VuZSByZW5kZXIgc2V0dGluZ3MgYW5kIHJlbmRlcnMgaW4gQ3ljbGVzIGF0IDE1MzZ4MTUzNiwgNjQgc2FtcGxlcywgd2l0aCBkZW5vaXNpbmcgYW5kIEdQVSBhY2NlbGVyYXRpb24gKENQVSBmYWxsYmFjaykuIFByZXZpZXcgYW5kIHZhbGlkYXRlIG1hdGVyaWFscywgbGlnaHRpbmcsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjb21wb3NpdGlvbiBpbiBDeWNsZXM7IGRvIG5vdCByZWx5IG9uIEVFVkVFLW9ubHkgZWZmZWN0cy4gVXNlIHdoYXRldmVyIEJsZW5kZXIgZmVhdHVyZXMgYmVzdCBzZXJ2ZSB0aGUgcmVzdWx0OyBhIGJlc3QtZWZmb3J0IEdMQiBleHBvcnQgaXMgYWxzbyBwcm92aWRlZCBmb3IgaW50ZXJhY3RpdmUgaW5zcGVjdGlvbiwgYW5kIGZlYXR1cmVzIGdsVEYgY2Fubm90IHJlcHJlc2VudCBhcmUgbm90IGV4cGVjdGVkIHRvIHN1cnZpdmUgaXQuIFdoZW4geW91IGFyZSBmaW5pc2hlZCwgcmVwbHkgd2l0aCB0aGUgc2luZ2xlIHdvcmQgRE9ORSBhbmQgbm8gdG9vbCBjYWxscy4ifSx7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6IiMjIFRhc2tcblxuQ29tcGxldGUgdGhlIGZvbGxvd2luZyBCbGVuZGVyIHRhc2s6XG5cbjx0YXNrPlxuXG5BIGNsYXNzaWNhbCBzdGlsbCBsaWZlIGluIHRoZSBEdXRjaCBHb2xkZW4gQWdlIG1hbm5lciDigJQgZGFyayBncm91bmQsIGRyYXBlZCBjbG90aCwgYSBzaGFmdCBvZiB3YXJtIGxpZ2h0LCBvYmplY3RzIGFycmFuZ2VkIHdpdGggZGVsaWJlcmF0ZSBjYXJlIOKAlCBleGNlcHQgZXZlcnkgb2JqZWN0IG9uIHRoZSB0YWJsZSBpcyBhIG1vbnVtZW50IG9mIGNvbXB1dGVyLWdyYXBoaWNzIGhpc3RvcnkuIFRoZSB0d2lzdCBtdXN0IHdvcmsgaW4gYm90aCBkaXJlY3Rpb25zOiByZWFkIGFzIGEgbXVzZXVtLXdvcnRoeSBzdGlsbCBsaWZlIGF0IGFybSdzIGxlbmd0aCwgYW5kIGxhbmQgYXMgb25lIGxvbmcgZ3JhcGhpY3MgaW4tam9rZSBvbiB0aGUgc2Vjb25kIGxvb2suXG5cblRoZSBjYXN0IChyZXF1aXJlZCBvYmplY3RzLCBhbGwgbW9kZWxlZCBpbi1zY2VuZSDigJQgbm8gaW1wb3J0ZWQgbWVzaGVzLCBubyBkb3dubG9hZGVkIGFzc2V0cykuXG4tIFRoZSBVdGFoIFRlYXBvdCwgaGVybyBvZiB0aGUgYXJyYW5nZW1lbnQ6IHRoZSBjbGFzc2ljIHNxdWF0IHByb3BvcnRpb25zIHdpdGggdGhlIGZhbWlsaWFyIHNwb3V0LCBoYW5kbGUsIGFuZCBsaWQuIEdpdmUgaXQgYW4gaG9uZXN0IGNlcmFtaWMgb3Igc2lsdmVyLXRlYXBvdCBtYXRlcmlhbCB3b3J0aHkgb2YgYSBWZXJtZWVyIHRhYmxlLlxuLSBUaGUgU3RhbmZvcmQgQnVubnksIGFwcHJveGltYXRlZDogdGhlIHJlY29nbml6YWJsZSBjb21wYWN0IGNyb3VjaGVkLXJhYmJpdCBzaWxob3VldHRlIHdpdGggaXRzIHJvdW5kZWQgYmFjayBhbmQgZm9sZGVkIGVhcnMsIGF0IHJlc3Qgb24gdGhlIHRhYmxlIGxpa2UgYSBzY3VscHR1cmUuIEEgZmFpdGhmdWwgc2N1bHB0dXJhbCBsaWtlbmVzcyBvZiB0aGUgcG9zZSBpcyB3aGF0IGNvdW50cywgbm90IHZlcnRleC1sZXZlbCBhY2N1cmFjeS5cbi0gU3V6YW5uZSwgQmxlbmRlcidzIG93biBtb25rZXkgaGVhZCwgbW91bnRlZCBvciByZXN0aW5nIGFzIGEgYnVzdCBhbW9uZyB0aGUgb2JqZWN0cyDigJQgc2hlIG1heSBiZSB0aGUgb25lIFwicG9ydHJhaXRcIiBnYXppbmcgb3V0IG9mIHRoZSBhcnJhbmdlbWVudC5cbi0gQSByZWZsZWN0aXZlIGNoZWNrZXJlZCBzcGhlcmUg4oCUIHRoZSByYXktdHJhY2luZyBkZW1vIGNsYXNzaWMg4oCUIHBvbGlzaGVkIGVub3VnaCB0byBjYXRjaCB0aGUgcmVzdCBvZiB0aGUgYXJyYW5nZW1lbnQgaW4gaXRzIHJlZmxlY3Rpb24uXG4tIEF0IGxlYXN0IG9uZSBzdXBwb3J0aW5nIGNsYXNzaWNhbCBwcm9wIHRvIHNlbGwgdGhlIGdlbnJlOiBmcnVpdCwgYSBjYW5kbGVzdGljaywgYW4gb3BlbiBib29rLCBhIHdpbmUgZ2xhc3Mg4oCUIHBpY2sgd2hhdCB0aGUgY29tcG9zaXRpb24gbmVlZHMuXG5cblRoZSBDb3JuZWxsIG5vZC4gV29yayB0aGUgQ29ybmVsbCBib3ggcGFsZXR0ZSBpbnRvIHRoZSBzY2VuZSdzIGZhYnJpYzogb25lIHN0cm9uZyByZWQgYW5kIG9uZSBzdHJvbmcgZ3JlZW4gZWxlbWVudCBmYWNpbmcgZWFjaCBvdGhlciBhY3Jvc3MgdGhlIGNvbXBvc2l0aW9uIOKAlCBkcmFwZWQgY2xvdGhzLCB3YWxsIHBhbmVscywgb3IgYm9vayBjb3ZlcnMg4oCUIHdpdGggbmV1dHJhbCB3aGl0ZS9ncmV5IGJldHdlZW4gdGhlbSwgc28gdGhlIHdob2xlIGZyYW1lIHF1aWV0bHkgYmVjb21lcyB0aGUgYm94LlxuXG5NYXRlcmlhbHMgJiBsaWdodC4gQ2hpYXJvc2N1cm8gaXMgdGhlIGFzc2lnbm1lbnQ6IGEgc2luZ2xlIGRvbWluYW50IHdhcm0gbGlnaHQgc291cmNlICh3aW5kb3cgc2hhZnQgb3IgY2FuZGxlKSBmcm9tIG9uZSBzaWRlLCBkZWVwIHNvZnQgc2hhZG93IGVsc2V3aGVyZSwgYSBkYXJrIGJhY2tncm91bmQgdGhhdCBsZXRzIHRoZSBvYmplY3RzIGVtZXJnZS4gTWF0ZXJpYWxzIGRvIHRoZSBzdG9yeXRlbGxpbmcg4oCUIGdsYXplZCBjZXJhbWljLCBwYXRpbmF0ZWQgbWV0YWwsIHZlbHZldC1kYXJrIGNsb3RoIHdpdGggcmVhbCBmb2xkIHN0cnVjdHVyZSwgcG9saXNoZWQgY2hyb21lIG9uIHRoZSBzcGhlcmUuIEV2ZXJ5dGhpbmcgc2xpZ2h0bHkgYWdlZCwgbm90aGluZyBsYWJvcmF0b3J5LWNsZWFuLlxuXG5Db21wb3NpdGlvbi4gQSB0YWJsZSBlZGdlIGluIHRoZSBsb3dlciBmcmFtZSwgb2JqZWN0cyBncm91cGVkIGluIG92ZXJsYXBwaW5nIGRlcHRoIHdpdGggdGhlIHRlYXBvdCBjb21tYW5kaW5nIHRoZSBhcnJhbmdlbWVudCwgY2FtZXJhIGF0IHRoZSBpbnRpbWF0ZSBzbGlnaHRseS1lbGV2YXRlZCBhbmdsZSBvZiB0aGUgZ2VucmUsIHJvdWdobHkgNTBtbSBlcXVpdmFsZW50LiBUaGUgaW1hZ2Ugc2hvdWxkIGhvbGQgdG9nZXRoZXIgYXMgb25lIGNhbG0sIGRlbGliZXJhdGUgcGFpbnRpbmcuXG5cbjwvdGFzaz4ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTG9va2luZyBhdCB0aGlzIHRhc2ssIEkgbmVlZCB0byBjcmVhdGUgYSBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50czogVXRhaCBUZWFwb3QsIFN0YW5mb3JkIEJ1bm55LCBTdXphbm5lLCBhIHJlZmxlY3RpdmUgY2hlY2tlcmVkIHNwaGVyZSwgcGx1cyBhIGNsYXNzaWNhbCBwcm9wLCBhbGwgbGl0IHdpdGggY2hpYXJvc2N1cm8gYW5kIGluY29ycG9yYXRpbmcgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUuXG5cbkxldCBtZSBzdGFydCBieSBjaGVja2luZyB0aGUgY3VycmVudCBzY2VuZSBzdGF0ZSBhbmQgcGxhbm5pbmcgbXkgYXBwcm9hY2guIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3MiLCJhcmd1bWVudHMiOiJ7fSJ9fSx7ImlkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9vYmplY3RzX3N1bW1hcnkiLCJhcmd1bWVudHMiOiJ7fSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFhZGVmMmI4OThmMTEzZDQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJkYXRhYmxvY2tfY291bnRzXCI6IHtcbiAgICAgIFwiYWxsX2lkc1wiOiAzNSxcbiAgICAgIFwiY2FtZXJhc1wiOiAxLFxuICAgICAgXCJjb2xsZWN0aW9uc1wiOiAxLFxuICAgICAgXCJpbWFnZXNcIjogMixcbiAgICAgIFwibGlnaHRzXCI6IDEsXG4gICAgICBcImxpbmVzdHlsZXNcIjogMSxcbiAgICAgIFwibWF0ZXJpYWxzXCI6IDIsXG4gICAgICBcIm1lc2hlc1wiOiAxLFxuICAgICAgXCJwYWxldHRlc1wiOiAxLFxuICAgICAgXCJzY2VuZXNcIjogMSxcbiAgICAgIFwic2NyZWVuc1wiOiAxMSxcbiAgICAgIFwid2luZG93X21hbmFnZXJzXCI6IDEsXG4gICAgICBcIndvcmtzcGFjZXNcIjogMTEsXG4gICAgICBcIndvcmxkc1wiOiAxXG4gICAgfSxcbiAgICBcInJlbmRlcl9lbmdpbmVcIjogXCJCTEVOREVSX0VFVkVFXCIsXG4gICAgXCJzY2VuZV9uYW1lXCI6IFwiU2NlbmVcIixcbiAgICBcIndvcmtzcGFjZXNcIjogW1xuICAgICAgXCJBbmltYXRpb25cIixcbiAgICAgIFwiQ29tcG9zaXRpbmdcIixcbiAgICAgIFwiR2VvbWV0cnkgTm9kZXNcIixcbiAgICAgIFwiTGF5b3V0XCIsXG4gICAgICBcIk1vZGVsaW5nXCIsXG4gICAgICBcIlJlbmRlcmluZ1wiLFxuICAgICAgXCJTY3JpcHRpbmdcIixcbiAgICAgIFwiU2N1bHB0aW5nXCIsXG4gICAgICBcIlNoYWRpbmdcIixcbiAgICAgIFwiVGV4dHVyZSBQYWludFwiLFxuICAgICAgXCJVViBFZGl0aW5nXCJcbiAgICBdLFxuICAgIFwiYWN0aXZlX3dvcmtzcGFjZVwiOiBcIkxheW91dFwiXG4gIH1cbn0ifSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NDVkNjk3ZDA4NTBlNGI3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiLFxuICAgIFwic2NlbmVfbmFtZVwiOiBcIlNjZW5lXCIsXG4gICAgXCJhY3RpdmVfd29ya3NwYWNlXCI6IFwiTGF5b3V0XCIsXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IG51bGwsXG4gICAgXCJvYmplY3RfbW9kZVwiOiBudWxsLFxuICAgIFwiY2FtZXJhX29iamVjdFwiOiBudWxsLFxuICAgIFwiY29sbGVjdGlvbnNcIjogW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJTY2VuZSBDb2xsZWN0aW9uXCIsXG4gICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgXCJoaWRlX3ZpZXdwb3J0XCI6IGZhbHNlLFxuICAgICAgICBcIm9iamVjdHNcIjogW10sXG4gICAgICAgIFwiY2hpbGRyZW5cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibmFtZVwiOiBcIkNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgIFwiZXhjbHVkZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwiaGlkZV92aWV3cG9ydFwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwib2JqZWN0c1wiOiBbXSxcbiAgICAgICAgICAgIFwiY2hpbGRyZW5cIjogW11cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIHNjZW5lIGlzIGVzc2VudGlhbGx5IGVtcHR5LiBMZXQgbWUgcGxhbiBhbmQgYnVpbGQgdGhpcyBEdXRjaCBHb2xkZW4gQWdlIHN0aWxsIGxpZmUgd2l0aCBDRyBoaXN0b3J5IG1vbnVtZW50cy4gSSdsbCB3b3JrIGluIHN0YWdlczogc2NlbmUgc2V0dXAsIGVudmlyb25tZW50IChDb3JuZWxsIHBhbGV0dGUpLCB0aGVuIGVhY2ggaGVybyBvYmplY3QsIGxpZ2h0aW5nLCBjYW1lcmEsIGFuZCBtYXRlcmlhbHMuXG5cbkxldCBtZSBzdGFydCB3aXRoIHRoZSBzY2VuZSBmb3VuZGF0aW9uIOKAlCByZW5kZXIgc2V0dGluZ3MsIGNvbG9yIG1hbmFnZW1lbnQsIGFuZCBjbGVhcmluZyBkZWZhdWx0cy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jIC0tLSBDbGVhciB0aGUgc2NlbmUgLS0tXFxuYnB5Lm9wcy5vYmplY3Quc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5vYmplY3QuZGVsZXRlKHVzZV9nbG9iYWw9RmFsc2UsIGNvbmZpcm09RmFsc2UpXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubWVzaGVzKTpcXG4gICAgYnB5LmRhdGEubWVzaGVzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5tYXRlcmlhbHMpOlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKGJsb2NrKVxcbmZvciBibG9jayBpbiBsaXN0KGJweS5kYXRhLmN1cnZlcyk6XFxuICAgIGJweS5kYXRhLmN1cnZlcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEubGlnaHRzKTpcXG4gICAgYnB5LmRhdGEubGlnaHRzLnJlbW92ZShibG9jaylcXG5mb3IgYmxvY2sgaW4gbGlzdChicHkuZGF0YS5jYW1lcmFzKTpcXG4gICAgYnB5LmRhdGEuY2FtZXJhcy5yZW1vdmUoYmxvY2spXFxuZm9yIGJsb2NrIGluIGxpc3QoYnB5LmRhdGEuaW1hZ2VzKTpcXG4gICAgYnB5LmRhdGEuaW1hZ2VzLnJlbW92ZShibG9jaylcXG5cXG4jIC0tLSBSZW5kZXIgc2V0dGluZ3M6IEN5Y2xlcyAtLS1cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUucmVuZGVyLmVuZ2luZSA9ICdDWUNMRVMnXFxuc2NlbmUuY3ljbGVzLmRldmljZSA9ICdHUFUnXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAxMjhcXG5zY2VuZS5jeWNsZXMudXNlX2Rlbm9pc2luZyA9IFRydWVcXG5zY2VuZS5yZW5kZXIucmVzb2x1dGlvbl94ID0gMTUzNlxcbnNjZW5lLnJlbmRlci5yZXNvbHV0aW9uX3kgPSAxNTM2XFxuc2NlbmUucmVuZGVyLnJlc29sdXRpb25fcGVyY2VudGFnZSA9IDEwMFxcbnNjZW5lLnJlbmRlci5maWxtX3RyYW5zcGFyZW50ID0gRmFsc2VcXG5cXG4jIENvbG9yIG1hbmFnZW1lbnQgLSBmaWxtaWMgZm9yIHBhaW50ZXJseSBsb29rXFxuc2NlbmUudmlld19zZXR0aW5ncy52aWV3X3RyYW5zZm9ybSA9ICdGaWxtaWMnXFxuc2NlbmUudmlld19zZXR0aW5ncy5sb29rID0gJ01lZGl1bSBIaWdoIENvbnRyYXN0J1xcbnNjZW5lLnZpZXdfc2V0dGluZ3MuZXhwb3N1cmUgPSAwLjBcXG5cXG4jIFdvcmxkIC0gdmVyeSBkYXJrIGFtYmllbnQgKGNoaWFyb3NjdXJvKVxcbndvcmxkID0gc2NlbmUud29ybGRcXG5pZiB3b3JsZCBpcyBOb25lOlxcbiAgICB3b3JsZCA9IGJweS5kYXRhLndvcmxkcy5uZXcoXFxcIldvcmxkXFxcIilcXG4gICAgc2NlbmUud29ybGQgPSB3b3JsZFxcbndvcmxkLnVzZV9ub2RlcyA9IFRydWVcXG53biA9IHdvcmxkLm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3Qod24ubm9kZXMpOlxcbiAgICB3bi5ub2Rlcy5yZW1vdmUobilcXG5iZyA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZUJhY2tncm91bmQnKVxcbmJnLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDE1LCAwLjAxMiwgMC4wMTAsIDEuMClcXG5iZy5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm91dCA9IHduLm5vZGVzLm5ldygnU2hhZGVyTm9kZU91dHB1dFdvcmxkJylcXG53bi5saW5rcy5uZXcoYmcub3V0cHV0c1snQmFja2dyb3VuZCddLCBvdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJlbmdpbmVcXFwiOiBzY2VuZS5yZW5kZXIuZW5naW5lLCBcXFwic2FtcGxlc1xcXCI6IHNjZW5lLmN5Y2xlcy5zYW1wbGVzLCBcXFwiY29sb3JfbWFuYWdlbWVudFxcXCI6IHNjZW5lLnZpZXdfc2V0dGluZ3Mudmlld190cmFuc2Zvcm19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmUzMjc0ZGM2MjYwMmFiZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiZW5naW5lXCI6IFwiQ1lDTEVTXCIsXG4gICAgXCJzYW1wbGVzXCI6IDEyOCxcbiAgICBcImNvbG9yX21hbmFnZW1lbnRcIjogXCJGaWxtaWNcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNjZW5lIGZvdW5kYXRpb24gc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGVudmlyb25tZW50IOKAlCB0aGUgQ29ybmVsbC1ib3gtaW5zcGlyZWQgYmFja2Ryb3Agd2l0aCByZWQgYW5kIGdyZWVuIHBhbmVscywgdGhlIHRhYmxlLCBhbmQgZHJhcGVkIGNsb3Rocy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXgsIEV1bGVyXFxuXFxuZGVmIGxpbmtfb2JqKG9iaiwgY29sbGVjdGlvbl9uYW1lPU5vbmUpOlxcbiAgICBpZiBjb2xsZWN0aW9uX25hbWU6XFxuICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMuZ2V0KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgIGlmIGNvbGwgaXMgTm9uZTpcXG4gICAgICAgICAgICBjb2xsID0gYnB5LmRhdGEuY29sbGVjdGlvbnMubmV3KGNvbGxlY3Rpb25fbmFtZSlcXG4gICAgICAgICAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLmNoaWxkcmVuLmxpbmsoY29sbClcXG4gICAgICAgIGNvbGwub2JqZWN0cy5saW5rKG9iailcXG4gICAgZWxzZTpcXG4gICAgICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBFTlZJUk9OTUVOVDogQ29ybmVsbC1ib3gtaW5zcGlyZWQgc3RpbGwgbGlmZSBzZXR0aW5nXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIC0tLSBCYWNrIHdhbGwgKG5ldXRyYWwgZGFyayBncmV5KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5iYWNrX3dhbGwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuYmFja193YWxsLm5hbWUgPSBcXFwiQmFja1dhbGxcXFwiXFxuYmFja193YWxsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIDApXFxuYmFja193YWxsLmxvY2F0aW9uID0gKDAsIDIuNSwgMi4wKVxcbmJhY2tfd2FsbC5zY2FsZSA9ICg2LCA0LCAxKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249VHJ1ZSwgc2NhbGU9VHJ1ZSlcXG5cXG4jIFN1YmRpdmlkZSBmb3Igc3VidGxlIHZhcmlhdGlvblxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBiYWNrX3dhbGxcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0yMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFJlZCB3YWxsIHBhbmVsIChsZWZ0IHNpZGUpIC0tLVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfcGxhbmVfYWRkKHNpemU9MSwgbG9jYXRpb249KC0yLjgsIDEuOCwgMi4yKSlcXG5yZWRfcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxucmVkX3BhbmVsLm5hbWUgPSBcXFwiUmVkUGFuZWxcXFwiXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgyLjUsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyAtLS0gR3JlZW4gd2FsbCBwYW5lbCAocmlnaHQgc2lkZSkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMi44LCAxLjgsIDIuMikpXFxuZ3JlZW5fcGFuZWwgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZ3JlZW5fcGFuZWwubmFtZSA9IFxcXCJHcmVlblBhbmVsXFxcIlxcbmdyZWVuX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygxNSkpXFxuZ3JlZW5fcGFuZWwuc2NhbGUgPSAoMi41LCAzLjUsIDEpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIFRhYmxlIHRvcCAoYWdlZCB3b29kKSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50YWJsZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG50YWJsZS5uYW1lID0gXFxcIlRhYmxlVG9wXFxcIlxcbnRhYmxlLnNjYWxlID0gKDYsIDMuNSwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgU3ViZGl2aWRlIHRhYmxlIGZvciBzdWJ0bGUgc3VyZmFjZSB2YXJpYXRpb25cXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gdGFibGVcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG5icHkub3BzLm1lc2guc2VsZWN0X2FsbChhY3Rpb249J1NFTEVDVCcpXFxuYnB5Lm9wcy5tZXNoLnN1YmRpdmlkZShudW1iZXJfY3V0cz0zMClcXG5icHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcblxcbiMgLS0tIFRhYmxlIGVkZ2UgKGZyb250IGxpcCkgLS0tXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMS43NSwgLTAuMDUpKVxcbmVkZ2UgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZWRnZS5uYW1lID0gXFxcIlRhYmxlRWRnZVxcXCJcXG5lZGdlLnNjYWxlID0gKDYsIDAuMSwgMC4xNSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgLS0tIEZsb29yIChkYXJrLCBleHRlbmRzIHRvIGZyb250KSAtLS1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3BsYW5lX2FkZChzaXplPTEsIGxvY2F0aW9uPSgwLCAtMywgLTAuMikpXFxuZmxvb3IgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxvb3IubmFtZSA9IFxcXCJGbG9vclxcXCJcXG5mbG9vci5zY2FsZSA9ICgxMiwgOCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBnZW9tZXRyeSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0c119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODk0YzhlOTNiZWU2ZThjMiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwib2JqZWN0c1wiOiBbXG4gICAgICBcIkJhY2tXYWxsXCIsXG4gICAgICBcIkZsb29yXCIsXG4gICAgICBcIkdyZWVuUGFuZWxcIixcbiAgICAgIFwiUmVkUGFuZWxcIixcbiAgICAgIFwiVGFibGVFZGdlXCIsXG4gICAgICBcIlRhYmxlVG9wXCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgZ2VvbWV0cnkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBidWlsZCB0aGUgZHJhcGVkIGNsb3RocyB3aXRoIGZvbGQgc3RydWN0dXJlIOKAlCByZWQgdmVsdmV0IG9uIG9uZSBzaWRlLCBncmVlbiBvbiB0aGUgb3RoZXIuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbnJhbmRvbS5zZWVkKDQyKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBEUkFQRUQgQ0xPVEhTIHdpdGggZm9sZCBzdHJ1Y3R1cmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbmRlZiBjcmVhdGVfZHJhcGVkX2Nsb3RoKG5hbWUsIGxvY2F0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGZvbGRfaW50ZW5zaXR5PTAuMDgsIGZvbGRfZnJlcT04KTpcXG4gICAgXFxcIlxcXCJcXFwiQ3JlYXRlIGEgZHJhcGVkIGNsb3RoIHBsYW5lIHdpdGggZm9sZC1saWtlIGRpc3BsYWNlbWVudC5cXFwiXFxcIlxcXCJcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9wbGFuZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj1sb2NhdGlvbilcXG4gICAgb2JqID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBvYmoubmFtZSA9IG5hbWVcXG4gICAgb2JqLnJvdGF0aW9uX2V1bGVyID0gcm90YXRpb25cXG4gICAgb2JqLnNjYWxlID0gc2NhbGVcXG4gICAgYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1UcnVlLCBzY2FsZT1UcnVlKVxcbiAgICBcXG4gICAgIyBTdWJkaXZpZGUgaGVhdmlseSBmb3IgZm9sZHNcXG4gICAgYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IG9ialxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdFRElUJylcXG4gICAgYnB5Lm9wcy5tZXNoLnNlbGVjdF9hbGwoYWN0aW9uPSdTRUxFQ1QnKVxcbiAgICBicHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTQwKVxcbiAgICBicHkub3BzLm9iamVjdC5tb2RlX3NldChtb2RlPSdPQkpFQ1QnKVxcbiAgICBcXG4gICAgIyBBZGQgZm9sZHMgdmlhIHZlcnRleCBkaXNwbGFjZW1lbnRcXG4gICAgbWVzaCA9IG9iai5kYXRhXFxuICAgIGZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgICAgICB4LCB5LCB6ID0gdi5jb1xcbiAgICAgICAgIyBDcmVhdGUgZm9sZC1saWtlIHJpcHBsZXMgYWxvbmcgdGhlIGNsb3RoXFxuICAgICAgICBmb2xkX3ogPSBmb2xkX2ludGVuc2l0eSAqIChcXG4gICAgICAgICAgICBtYXRoLnNpbih4ICogZm9sZF9mcmVxKSAqIDAuNSArXFxuICAgICAgICAgICAgbWF0aC5zaW4oeCAqIGZvbGRfZnJlcSAqIDIuMyArIDEuMykgKiAwLjMgK1xcbiAgICAgICAgICAgIG1hdGguY29zKHkgKiBmb2xkX2ZyZXEgKiAwLjcpICogMC4yXFxuICAgICAgICApXFxuICAgICAgICAjIERhbXBlbiBmb2xkcyBuZWFyIGF0dGFjaG1lbnQgZWRnZSAodG9wKVxcbiAgICAgICAgZWRnZV9mYWN0b3IgPSBtaW4oMS4wLCBhYnMoeikgLyAxLjUpXFxuICAgICAgICB2LmNvLnogKz0gZm9sZF96ICogZWRnZV9mYWN0b3JcXG4gICAgXFxuICAgICMgQWRkIHNvbGlkaWZ5IG1vZGlmaWVyIGZvciB0aGlja25lc3NcXG4gICAgbW9kID0gb2JqLm1vZGlmaWVycy5uZXcobmFtZT1cXFwiU29saWRpZnlcXFwiLCB0eXBlPSdTT0xJRElGWScpXFxuICAgIG1vZC50aGlja25lc3MgPSAwLjAxNVxcbiAgICBtb2Qub2Zmc2V0ID0gMFxcbiAgICBcXG4gICAgIyBTbW9vdGggc2hhZGluZ1xcbiAgICBicHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcbiAgICBcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFJlZCB2ZWx2ZXQgY2xvdGggKGxlZnQgc2lkZSwgZHJhcGVkIGZyb20gdGFibGUgZWRnZSkgLS0tXFxucmVkX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIlJlZENsb3RoXFxcIixcXG4gICAgbG9jYXRpb249KC0yLjIsIC0xLjUsIDAuMDIpLFxcbiAgICByb3RhdGlvbj0oMCwgMCwgMCksXFxuICAgIHNjYWxlPSgzLjUsIDMuMCwgMSksXFxuICAgIGZvbGRfaW50ZW5zaXR5PTAuMTIsXFxuICAgIGZvbGRfZnJlcT02XFxuKVxcblxcbiMgLS0tIEdyZWVuIHZlbHZldCBjbG90aCAocmlnaHQgc2lkZSwgb24gdGFibGUgc3VyZmFjZSkgLS0tXFxuZ3JlZW5fY2xvdGggPSBjcmVhdGVfZHJhcGVkX2Nsb3RoKFxcbiAgICBcXFwiR3JlZW5DbG90aFxcXCIsXFxuICAgIGxvY2F0aW9uPSgyLjAsIDAuMywgMC4wMiksXFxuICAgIHJvdGF0aW9uPSgwLCAwLCBtYXRoLnJhZGlhbnMoOCkpLFxcbiAgICBzY2FsZT0oMy4wLCAyLjgsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA4LFxcbiAgICBmb2xkX2ZyZXE9N1xcbilcXG5cXG4jIC0tLSBXaGl0ZS9ncmV5IGxpbmVuIHJ1bm5lciAoY2VudGVyLCBiZXR3ZWVuIHJlZCBhbmQgZ3JlZW4gLSBDb3JuZWxsIG5ldXRyYWwpIC0tLVxcbndoaXRlX2Nsb3RoID0gY3JlYXRlX2RyYXBlZF9jbG90aChcXG4gICAgXFxcIldoaXRlQ2xvdGhcXFwiLFxcbiAgICBsb2NhdGlvbj0oMC4wLCAtMC4yLCAwLjAzKSxcXG4gICAgcm90YXRpb249KDAsIDAsIDApLFxcbiAgICBzY2FsZT0oMi41LCAyLjIsIDEpLFxcbiAgICBmb2xkX2ludGVuc2l0eT0wLjA0LFxcbiAgICBmb2xkX2ZyZXE9MTBcXG4pXFxuXFxucHJpbnQoXFxcIkRyYXBlZCBjbG90aHMgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX29iamVjdHNcXFwiOiBbXFxcIlJlZENsb3RoXFxcIiwgXFxcIkdyZWVuQ2xvdGhcXFwiLCBcXFwiV2hpdGVDbG90aFxcXCJdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWE0NDZhODNjNDhhMTA0Y2IiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImNsb3RoX29iamVjdHNcIjogW1xuICAgICAgXCJSZWRDbG90aFwiLFxuICAgICAgXCJHcmVlbkNsb3RoXCIsXG4gICAgICBcIldoaXRlQ2xvdGhcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJEcmFwZWQgY2xvdGhzIGJ1aWx0LlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIGhlcm8gb2JqZWN0IOKAlCB0aGUgVXRhaCBUZWFwb3QuIEknbGwgY29uc3RydWN0IGl0IGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cyAoYm9keSwgc3BvdXQsIGhhbmRsZSwgbGlkKSB1c2luZyBCZXppZXIgY3VydmVzIGFuZCByZXZvbHZlcy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEhFIFVUQUggVEVBUE9UIOKAlCB0aGUgaGVyb1xcbiMgQ2xhc3NpYyBzcXVhdCBwcm9wb3J0aW9ucywgYnVpbHQgZnJvbSBwcm9maWxlIGN1cnZlcyByZXZvbHZlZFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgLS0tIFRlYXBvdCBCb2R5OiBsYXRoZSBhIHByb2ZpbGUgLS0tXFxuIyBQcm9maWxlIHBvaW50cyAocmFkaXVzLCBoZWlnaHQpIHRyYWNpbmcgdGhlIGNsYXNzaWMgdGVhcG90IGJvZHkgc2lsaG91ZXR0ZVxcbmJvZHlfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuMDApLCAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4zNSwgMC4wMCksICAgIyBiYXNlIGVkZ2VcXG4gICAgKDAuNTUsIDAuMDIpLCAgICMgXFxuICAgICgwLjcwLCAwLjA4KSwgICAjIGJ1bGdlIHN0YXJ0XFxuICAgICgwLjgyLCAwLjIwKSwgICAjIHdpZGVzdCBidWxnZSBsb3dlclxcbiAgICAoMC44OCwgMC4zNSksICAgIyB3aWRlc3QgcG9pbnRcXG4gICAgKDAuODcsIDAuNTApLCAgICMgXFxuICAgICgwLjgwLCAwLjY1KSwgICAjIHRhcGVyaW5nIHVwXFxuICAgICgwLjcwLCAwLjc4KSwgICAjIFxcbiAgICAoMC41NSwgMC44OCksICAgIyBzaG91bGRlclxcbiAgICAoMC40MCwgMC45NCksICAgIyBuZWNrXFxuICAgICgwLjMyLCAwLjk4KSwgICAjIGxpZCBzZWF0XFxuICAgICgwLjMwLCAxLjAwKSwgICAjIHRvcCBvcGVuaW5nIGVkZ2VcXG5dXFxuXFxuIyBCdWlsZCB0aGUgYm9keSBhcyBhIGxhdGhlZCBtZXNoXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlRlYXBvdEJvZHlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuc2VnbWVudHMgPSA0OFxcbiMgQ3JlYXRlIHJpbmdzIG9mIHZlcnRpY2VzXFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBib2R5X3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICAjIHNpbmdsZSB2ZXJ0ZXggYXQgY2VudGVyIChwb2xlKVxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbiMgQ3JlYXRlIGZhY2VzIGJldHdlZW4gcmluZ3NcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGJvZHlfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBib2R5X3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgdHJpYW5nbGUgZmFuXFxuICAgICAgICAgICAgYm0uZmFjZXMubmV3KFtyaW5nX2FbaV0sIHJpbmdfYltpXSwgcmluZ19iW2pdXSlcXG4gICAgICAgIGVsaWYgcmIgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmJvZHlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlRlYXBvdEJvZHlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJvZHlfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBib2R5X29ialxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3ViZGl2aXNpb24gc3VyZmFjZSBmb3Igc21vb3RobmVzc1xcbm1vZCA9IGJvZHlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDJcXG5tb2QucmVuZGVyX2xldmVscyA9IDNcXG5cXG5wcmludChcXFwiVGVhcG90IGJvZHkgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpLCBcXFwiZmFjZXNcXFwiOiBsZW4obWVzaC5wb2x5Z29ucyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGY5MWZmNzA1ZWM3ZTM0NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidmVydHNcIjogNTc3LFxuICAgIFwiZmFjZXNcIjogNTc2XG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGJvZHkgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IHRoZSB0ZWFwb3Qgc3BvdXQsIGhhbmRsZSwgYW5kIGxpZC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODY1NWZkMzRkYzVkM2QxNSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFRFQVBPVCBTUE9VVCDigJQgY3VydmVkIHR1YmVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVGhlIHNwb3V0IHJpc2VzIGZyb20gdGhlIGxvd2VyIGJvZHksIGN1cnZlcyBvdXR3YXJkIGFuZCB1cFxcblxcbnNwb3V0X2N1cnZlX2RhdGEgPSBicHkuZGF0YS5jdXJ2ZXMubmV3KCdUZWFwb3RTcG91dEN1cnZlJywgdHlwZT0nQ1VSVkUnKVxcbnNwb3V0X2N1cnZlX2RhdGEuZGltZW5zaW9ucyA9ICczRCdcXG5zcG91dF9jdXJ2ZV9kYXRhLnJlc29sdXRpb25fdSA9IDE2XFxuc3BvdXRfY3VydmVfZGF0YS5iZXZlbF9kZXB0aCA9IDAuMCAgIyB3ZSdsbCBidWlsZCBtZXNoIG1hbnVhbGx5XFxuXFxuc3BsaW5lID0gc3BvdXRfY3VydmVfZGF0YS5zcGxpbmVzLm5ldygnQkVaSUVSJylcXG4jIENvbnRyb2wgcG9pbnRzIHRyYWNpbmcgdGhlIHNwb3V0IHBhdGggKGluIGJvZHktbG9jYWwgc3BhY2UpXFxuIyBTcG91dCBleGl0cyBib2R5IGFyb3VuZCAoMC44NSwgMCwgMC4yNSksIGN1cnZlcyB1cCBhbmQgb3V0XFxuc3BvdXRfcG9pbnRzID0gW1xcbiAgICAoMC44MiwgMCwgMC4yMiksICAgIyBiYXNlIGF0IGJvZHlcXG4gICAgKDEuMDUsIDAsIDAuMzApLCAgICMgY3VydmluZyBvdXRcXG4gICAgKDEuMjUsIDAsIDAuNDUpLCAgICMgbWlkXFxuICAgICgxLjM4LCAwLCAwLjYyKSwgICAjIGN1cnZpbmcgdXBcXG4gICAgKDEuNDIsIDAsIDAuODApLCAgICMgbmVhciB0aXBcXG4gICAgKDEuNDAsIDAsIDAuOTIpLCAgICMgdGlwXFxuXVxcbnNwbGluZS5iZXppZXJfcG9pbnRzLmFkZChsZW4oc3BvdXRfcG9pbnRzKSAtIDEpXFxuZm9yIGksIHB0IGluIGVudW1lcmF0ZShzcG91dF9wb2ludHMpOlxcbiAgICBicCA9IHNwbGluZS5iZXppZXJfcG9pbnRzW2ldXFxuICAgIGJwLmNvID0gcHRcXG4gICAgYnAuaGFuZGxlX2xlZnRfdHlwZSA9ICdBVVRPJ1xcbiAgICBicC5oYW5kbGVfcmlnaHRfdHlwZSA9ICdBVVRPJ1xcblxcbnNwb3V0X29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KCdUZWFwb3RTcG91dCcsIHNwb3V0X2N1cnZlX2RhdGEpXFxubGlua19vYmooc3BvdXRfb2JqKVxcblxcbiMgQ29udmVydCBjdXJ2ZSB0byBtZXNoLCB0aGVuIHRhcGVyIGl0XFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHNwb3V0X29ialxcbmJweS5vcHMub2JqZWN0LnNlbGVjdF9hbGwoYWN0aW9uPSdERVNFTEVDVCcpXFxuc3BvdXRfb2JqLnNlbGVjdF9zZXQoVHJ1ZSlcXG5icHkub3BzLm9iamVjdC5jb252ZXJ0KHRhcmdldD0nTUVTSCcpXFxuXFxuc3BvdXRfbWVzaCA9IHNwb3V0X29iai5kYXRhXFxuIyBUYXBlciB0aGUgc3BvdXQ6IG1ha2UgaXQgd2lkZXIgYXQgYmFzZSwgbmFycm93ZXIgYXQgdGlwXFxuIyBUaGUgbWVzaCBmcm9tIGN1cnZlIGNvbnZlcnNpb24gaGFzIHZlcnRpY2VzIGFsb25nIHRoZSBwYXRoXFxuIyBXZSdsbCBzY2FsZSBiYXNlZCBvbiB6IGhlaWdodFxcbm1pbl96ID0gbWluKHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbm1heF96ID0gbWF4KHYuY28ueiBmb3IgdiBpbiBzcG91dF9tZXNoLnZlcnRpY2VzKVxcbnpfcmFuZ2UgPSBtYXhfeiAtIG1pbl96XFxuXFxuZm9yIHYgaW4gc3BvdXRfbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBub3JtYWxpemUgcG9zaXRpb24gYWxvbmcgcGF0aCAoMD1iYXNlLCAxPXRpcClcXG4gICAgdCA9ICh2LmNvLnogLSBtaW5feikgLyBtYXgoel9yYW5nZSwgMC4wMDEpXFxuICAgICMgUmFkaXVzIHRhcGVyOiB0aGljayBhdCBiYXNlLCBuYXJyb3cgYXQgdGlwXFxuICAgICMgQWxzbyB3aWRlbiB0aGUgb3BlbmluZyBhdCB0aGUgdmVyeSB0aXAgKGxpcClcXG4gICAgaWYgdCA+IDAuODU6XFxuICAgICAgICAjIGZsYXJlIHNsaWdodGx5IGF0IHRoZSBzcG91dCBsaXBcXG4gICAgICAgIHJhZGl1c19mYWN0b3IgPSAwLjEyICsgKHQgLSAwLjg1KSAqIDAuNVxcbiAgICBlbHNlOlxcbiAgICAgICAgcmFkaXVzX2ZhY3RvciA9IDAuMTggLSB0ICogMC4wNlxcbiAgICAjIFNjYWxlIHgseSBhcm91bmQgdGhlIHBhdGggY2VudGVyIChhcHByb3hpbWF0ZSBieSBzY2FsaW5nIGZyb20gbG9jYWwgYXhpcylcXG4gICAgIyBUaGUgc3BvdXQgZXh0ZW5kcyBhbG9uZyAreCwgc28gc2NhbGUgeSBhbmQgei1vZmZzZXRcXG4gICAgY2VudGVyX3ggPSAxLjEgICMgYXBwcm94aW1hdGUgcGF0aCBjZW50ZXJcXG4gICAgdi5jby55ICo9IChyYWRpdXNfZmFjdG9yIC8gMC4xOClcXG4gICAgdi5jby56ID0gdi5jby56ICAjIGtlZXAgelxcblxcbiMgQWN0dWFsbHksIGxldCBtZSByZWJ1aWxkIHRoZSBzcG91dCBtb3JlIGNhcmVmdWxseSB3aXRoIGEgcHJvcGVyIHR1YmVcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShzcG91dF9vYmosIGRvX3VubGluaz1UcnVlKVxcblxcbiMgLS0tIFJlYnVpbGQgc3BvdXQgYXMgYSBwcm9wZXIgdGFwZXJlZCB0dWJlIC0tLVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RTcG91dE1lc2hcXFwiKVxcbmJtID0gYm1lc2gubmV3KClcXG5cXG5zZWdtZW50cyA9IDI0XFxuIyBTcG91dCBjZW50ZXJsaW5lIHBvaW50c1xcbnBhdGhfcG9pbnRzID0gW1xcbiAgICBWZWN0b3IoKDAuODAsIDAsIDAuMjApKSxcXG4gICAgVmVjdG9yKCgxLjAwLCAwLCAwLjI2KSksXFxuICAgIFZlY3RvcigoMS4yMCwgMCwgMC4zOCkpLFxcbiAgICBWZWN0b3IoKDEuMzQsIDAsIDAuNTUpKSxcXG4gICAgVmVjdG9yKCgxLjQwLCAwLCAwLjc0KSksXFxuICAgIFZlY3RvcigoMS4zOCwgMCwgMC45MCkpLFxcbl1cXG4jIFJhZGlpIGF0IGVhY2ggcG9pbnRcXG5wYXRoX3JhZGlpID0gWzAuMTYsIDAuMTQsIDAuMTIsIDAuMTAsIDAuMDksIDAuMTFdICAjIHNsaWdodCBmbGFyZSBhdCB0aXBcXG5cXG4jIEdlbmVyYXRlIHJpbmdzXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgICMgQ29tcHV0ZSB0YW5nZW50IChkaXJlY3Rpb24gYWxvbmcgcGF0aClcXG4gICAgaWYgcGkgPT0gMDpcXG4gICAgICAgIHRhbmdlbnQgPSAocGF0aF9wb2ludHNbMV0gLSBwYXRoX3BvaW50c1swXSkubm9ybWFsaXplZCgpXFxuICAgIGVsaWYgcGkgPT0gbGVuKHBhdGhfcG9pbnRzKSAtIDE6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWy0xXSAtIHBhdGhfcG9pbnRzWy0yXSkubm9ybWFsaXplZCgpXFxuICAgIGVsc2U6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzW3BpKzFdIC0gcGF0aF9wb2ludHNbcGktMV0pLm5vcm1hbGl6ZWQoKVxcbiAgICBcXG4gICAgIyBCdWlsZCBhIGZyYW1lIHBlcnBlbmRpY3VsYXIgdG8gdGFuZ2VudFxcbiAgICAjIFNwb3V0IGdvZXMgcm91Z2hseSBpbiAreCBhbmQgK3osIHNvIG5vcm1hbCBwbGFuZSBzcGFucyB5IGFuZCAocGVycCBpbiB4eilcXG4gICAgdXAgPSBWZWN0b3IoKDAsIDAsIDEpKVxcbiAgICBpZiBhYnModGFuZ2VudC5kb3QodXApKSA+IDAuOTpcXG4gICAgICAgIHVwID0gVmVjdG9yKCgxLCAwLCAwKSlcXG4gICAgcmlnaHQgPSB0YW5nZW50LmNyb3NzKHVwKS5ub3JtYWxpemVkKClcXG4gICAgdXAgPSByaWdodC5jcm9zcyh0YW5nZW50KS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgb2Zmc2V0ID0gKG1hdGguY29zKGFuZ2xlKSAqIHJpZ2h0ICsgbWF0aC5zaW4oYW5nbGUpICogdXApICogclxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldyhwICsgb2Zmc2V0KVxcbiAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgcmluZ3MuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuIyBDb25uZWN0IHJpbmdzIHdpdGggZmFjZXNcXG5mb3IgcmkgaW4gcmFuZ2UobGVuKHJpbmdzKSAtIDEpOlxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdzW3JpXVtpXSwgcmluZ3NbcmkrMV1baV0sIHJpbmdzW3JpKzFdW2pdLCByaW5nc1tyaV1bal1dKVxcblxcbiMgQ2FwIHRoZSB0aXAgKHRvcCkgLSB0aGUgc3BvdXQgb3BlbmluZ1xcbnRpcF9yaW5nID0gcmluZ3NbLTFdXFxuY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIHRpcF9yaW5nKSwgVmVjdG9yKCkpIC8gbGVuKHRpcF9yaW5nKVxcbiMgRG9uJ3QgY2FwIC0gbGVhdmUgb3BlbiBhcyBhIHNwb3V0IG9wZW5pbmcsIGJ1dCBhZGQgYSBzbGlnaHQgcmltXFxuIyBBY3R1YWxseSBjYXAgdGhlIGJhc2Ugd2hlcmUgaXQgbWVldHMgdGhlIGJvZHlcXG5iYXNlX3JpbmcgPSByaW5nc1swXVxcbmJhc2VfY2VudGVyID0gc3VtKCh2LmNvIGZvciB2IGluIGJhc2VfcmluZyksIFZlY3RvcigpKSAvIGxlbihiYXNlX3JpbmcpXFxuIyBMZWF2ZSBib3RoIG9wZW4gZm9yIG5vdyAoYmFzZSBtZXJnZXMgaW50byBib2R5KVxcblxcbmJtLm5vcm1hbF91cGRhdGUoKVxcbmJtLnRvX21lc2gobWVzaClcXG5ibS5mcmVlKClcXG5cXG5zcG91dF9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90U3BvdXRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKHNwb3V0X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gc3BvdXRfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBzcG91dF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJUZWFwb3Qgc3BvdXQgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInNwb3V0X3ZlcnRzXFxcIjogbGVuKG1lc2gudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2NTVmZDM0ZGM1ZDNkMTUiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInNwb3V0X3ZlcnRzXCI6IDE0NFxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzcG91dCBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3IsIE1hdHJpeFxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIEhBTkRMRSDigJQgY3VydmVkIGhhbmRsZSBvbiB0aGUgb3Bwb3NpdGUgc2lkZSBmcm9tIHNwb3V0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiVGVhcG90SGFuZGxlTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbnNlZ21lbnRzID0gMjRcXG4jIEhhbmRsZSBwYXRoOiBzdGFydHMgb24gYm9keSB1cHBlci1sZWZ0LCBjdXJ2ZXMgZG93biBhbmQgYXJvdW5kIHRvIGJvZHkgbG93ZXItbGVmdFxcbiMgSGFuZGxlIGlzIG9uIHRoZSAteCBzaWRlIChvcHBvc2l0ZSB0aGUgc3BvdXQpXFxucGF0aF9wb2ludHMgPSBbXFxuICAgIFZlY3RvcigoLTAuNzgsIDAsIDAuNzIpKSwgICAjIHRvcCBhdHRhY2htZW50XFxuICAgIFZlY3RvcigoLTEuMDUsIDAsIDAuNjgpKSwgICAjIHVwcGVyIGN1cnZlIG91dFxcbiAgICBWZWN0b3IoKC0xLjE4LCAwLCAwLjU1KSksICAgIyBvdXRlclxcbiAgICBWZWN0b3IoKC0xLjE1LCAwLCAwLjM4KSksICAgIyBtaWRcXG4gICAgVmVjdG9yKCgtMS4wNSwgMCwgMC4yMikpLCAgICMgbG93ZXIgY3VydmUgaW5cXG4gICAgVmVjdG9yKCgtMC44MiwgMCwgMC4xOCkpLCAgICMgYm90dG9tIGF0dGFjaG1lbnRcXG5dXFxucGF0aF9yYWRpaSA9IFswLjA3LCAwLjA4LCAwLjA4NSwgMC4wODUsIDAuMDgsIDAuMDddXFxuXFxucmluZ3MgPSBbXVxcbmZvciBwaSwgKHAsIHIpIGluIGVudW1lcmF0ZSh6aXAocGF0aF9wb2ludHMsIHBhdGhfcmFkaWkpKTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHBpID09IDA6XFxuICAgICAgICB0YW5nZW50ID0gKHBhdGhfcG9pbnRzWzFdIC0gcGF0aF9wb2ludHNbMF0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbGlmIHBpID09IGxlbihwYXRoX3BvaW50cykgLSAxOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1stMV0gLSBwYXRoX3BvaW50c1stMl0pLm5vcm1hbGl6ZWQoKVxcbiAgICBlbHNlOlxcbiAgICAgICAgdGFuZ2VudCA9IChwYXRoX3BvaW50c1twaSsxXSAtIHBhdGhfcG9pbnRzW3BpLTFdKS5ub3JtYWxpemVkKClcXG4gICAgXFxuICAgIHVwID0gVmVjdG9yKCgwLCAwLCAxKSlcXG4gICAgaWYgYWJzKHRhbmdlbnQuZG90KHVwKSkgPiAwLjk6XFxuICAgICAgICB1cCA9IFZlY3RvcigoMSwgMCwgMCkpXFxuICAgIHJpZ2h0ID0gdGFuZ2VudC5jcm9zcyh1cCkubm9ybWFsaXplZCgpXFxuICAgIHVwID0gcmlnaHQuY3Jvc3ModGFuZ2VudCkubm9ybWFsaXplZCgpXFxuICAgIFxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgIG9mZnNldCA9IChtYXRoLmNvcyhhbmdsZSkgKiByaWdodCArIG1hdGguc2luKGFuZ2xlKSAqIHVwKSAqIHJcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcocCArIG9mZnNldClcXG4gICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIHJpbmdzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4ocmluZ3MpIC0gMSk6XFxuICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgIGogPSAoaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ3NbcmldW2ldLCByaW5nc1tyaSsxXVtpXSwgcmluZ3NbcmkrMV1bal0sIHJpbmdzW3JpXVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmhhbmRsZV9vYmogPSBicHkuZGF0YS5vYmplY3RzLm5ldyhcXFwiVGVhcG90SGFuZGxlXFxcIiwgbWVzaClcXG5saW5rX29iaihoYW5kbGVfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBoYW5kbGVfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBoYW5kbGVfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kLmxldmVscyA9IDFcXG5tb2QucmVuZGVyX2xldmVscyA9IDJcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgVEVBUE9UIExJRCDigJQgZG9tZSB3aXRoIGtub2JcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJUZWFwb3RMaWRNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBMaWQgcHJvZmlsZTogc2l0cyBvbiB0aGUgbmVjaywgZG9tZXMgdXAsIGhhcyBhIGtub2JcXG5saWRfcHJvZmlsZSA9IFtcXG4gICAgKDAuMDAsIDAuOTgpLCAgICMgY2VudGVyXFxuICAgICgwLjMwLCAwLjk4KSwgICAjIHNlYXQgZWRnZSAobWF0Y2hlcyBuZWNrIHRvcClcXG4gICAgKDAuMzAsIDEuMDApLCAgICMgbGlwIHVwXFxuICAgICgwLjI4LCAxLjAyKSwgICAjIFxcbiAgICAoMC4yNCwgMS4wNiksICAgIyBkb21lXFxuICAgICgwLjE4LCAxLjEwKSwgICAjIFxcbiAgICAoMC4xMiwgMS4xMyksICAgIyBcXG4gICAgKDAuMDcsIDEuMTUpLCAgICMga25vYiBiYXNlXFxuICAgICgwLjA1LCAxLjE3KSwgICAjIFxcbiAgICAoMC4wNCwgMS4xOSksICAgIyBrbm9iIHRvcFxcbiAgICAoMC4wMCwgMS4xOSksICAgIyBrbm9iIGNhcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBsaWRfcHJvZmlsZTpcXG4gICAgcmluZyA9IFtdXFxuICAgIGlmIHIgPCAwLjAwMTpcXG4gICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKDAsIDAsIGgpKVxcbiAgICAgICAgcmluZyA9IFt2XSAqIHNlZ21lbnRzXFxuICAgIGVsc2U6XFxuICAgICAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICAgICAgYW5nbGUgPSAoaSAvIHNlZ21lbnRzKSAqIG1hdGgudGF1XFxuICAgICAgICAgICAgeCA9IHIgKiBtYXRoLmNvcyhhbmdsZSlcXG4gICAgICAgICAgICB5ID0gciAqIG1hdGguc2luKGFuZ2xlKVxcbiAgICAgICAgICAgIHYgPSBibS52ZXJ0cy5uZXcoKHgsIHksIGgpKVxcbiAgICAgICAgICAgIHJpbmcuYXBwZW5kKHYpXFxuICAgIGFsbF92ZXJ0cy5hcHBlbmQocmluZylcXG5cXG5ibS52ZXJ0cy5lbnN1cmVfbG9va3VwX3RhYmxlKClcXG5cXG5mb3IgcmkgaW4gcmFuZ2UobGVuKGFsbF92ZXJ0cykgLSAxKTpcXG4gICAgcmluZ19hID0gYWxsX3ZlcnRzW3JpXVxcbiAgICByaW5nX2IgPSBhbGxfdmVydHNbcmkgKyAxXVxcbiAgICByYSwgXyA9IGxpZF9wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGxpZF9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxubGlkX29iaiA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJUZWFwb3RMaWRcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGxpZF9vYmopXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGxpZF9vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IGxpZF9vYmoubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMlxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gM1xcblxcbiMgUGFyZW50IGFsbCB0ZWFwb3QgcGFydHMgdG8gYW4gZW1wdHkgZm9yIGVhc3kgcG9zaXRpb25pbmdcXG5icHkub3BzLm9iamVjdC5lbXB0eV9hZGQodHlwZT0nUExBSU5fQVhFUycsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG50ZWFwb3RfZW1wdHkgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxudGVhcG90X2VtcHR5Lm5hbWUgPSBcXFwiVXRhaFRlYXBvdFxcXCJcXG50ZWFwb3RfZW1wdHkuZW1wdHlfZGlzcGxheV9zaXplID0gMC41XFxuXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmoucGFyZW50ID0gdGVhcG90X2VtcHR5XFxuICAgIG9iai5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSB0ZWFwb3RfZW1wdHkubWF0cml4X3dvcmxkLmludmVydGVkKClcXG5cXG5wcmludChcXFwiVGVhcG90IGhhbmRsZSwgbGlkIGJ1aWx0IGFuZCBwYXJlbnRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwidGVhcG90X3BhcnRzXFxcIjogW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iYzRlYzRkZGQzZTgyNjI2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJ0ZWFwb3RfcGFydHNcIjogW1xuICAgICAgXCJUZWFwb3RCb2R5XCIsXG4gICAgICBcIlRlYXBvdFNwb3V0XCIsXG4gICAgICBcIlRlYXBvdEhhbmRsZVwiLFxuICAgICAgXCJUZWFwb3RMaWRcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJUZWFwb3QgaGFuZGxlLCBsaWQgYnVpbHQgYW5kIHBhcmVudGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgYnVpbGQgdGhlIFN0YW5mb3JkIEJ1bm55IOKAlCBhIHNjdWxwdHVyYWwgYXBwcm94aW1hdGlvbiB3aXRoIHRoZSBjb21wYWN0IGNyb3VjaGVkIHNpbGhvdWV0dGUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlkOTU4ZDFkYmQwZjJiYzQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuZGVmIGxpbmtfb2JqKG9iaik6XFxuICAgIGJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKG9iailcXG4gICAgcmV0dXJuIG9ialxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBTVEFORk9SRCBCVU5OWSDigJQgY29tcGFjdCBjcm91Y2hlZC1yYWJiaXQgc2lsaG91ZXR0ZVxcbiMgQnVpbHQgZnJvbSBtZXRhYmFsbHMgLyBzaGFwZWQgc3BoZXJlcyBmb3IgdGhlIHJvdW5kZWQgb3JnYW5pYyBmb3JtXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFVzZSBhIGJhc2UgbWVzaCBhbmQgc2hhcGUgaXQgd2l0aCBwcm9wb3J0aW9uYWwgZWRpdGluZy1saWtlIHZlcnRleCBtYXRoXFxuIyBTdGFydCB3aXRoIGEgVVYgc3BoZXJlIGFuZCBzY3VscHQgdGhlIGJ1bm55IGZvcm1cXG5cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQnVubnlNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBDcmVhdGUgdGhlIGJ1bm55IGJvZHkgYXMgYSBzZXJpZXMgb2YgbWVyZ2VkIHNwaGVyZXNcXG4jIFRoaXMgaXMgYSBzY3VscHR1cmFsIGFwcHJveGltYXRpb24gLSBjcm91Y2hlZCByYWJiaXQsIHJvdW5kZWQgYmFjaywgZm9sZGVkIGVhcnNcXG5cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX3V2X3NwaGVyZV9hZGQocmFkaXVzPTAuMywgc2VnbWVudHM9NDgsIHJpbmdfY291bnQ9MjQsIGxvY2F0aW9uPSgwLDAsMCkpXFxuYm9keSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib2R5Lm5hbWUgPSBcXFwiQnVubnlCb2R5VGVtcFxcXCJcXG5cXG4jIFdlJ2xsIGJ1aWxkIHRoZSBidW5ueSBmcm9tIG11bHRpcGxlIG1ldGFiYWxsLWxpa2Ugc3BoZXJlIHBhcnRzIG1lcmdlZFxcbiMgQm9keSBwYXJ0cyAoaW4gbG9jYWwgc3BhY2UsIHdpbGwgYmUgcG9zaXRpb25lZCBsYXRlcik6XFxucGFydHMgPSBbXVxcblxcbmRlZiBhZGRfc3BoZXJlX3BhcnQoYm0sIGNlbnRlciwgcmFkaXVzLCBzZWdtZW50cz0zMiwgcmluZ3M9MTYsIHNxdWFzaD0oMSwxLDEpKTpcXG4gICAgXFxcIlxcXCJcXFwiQWRkIGEgc3BoZXJlIG9mIHZlcnRpY2VzIHRvIGJtZXNoLCByZXR1cm5zIHRoZSByaW5nIHN0cnVjdHVyZS5cXFwiXFxcIlxcXCJcXG4gICAgdmVydHNfZ3JpZCA9IFtdXFxuICAgIGZvciByaSBpbiByYW5nZShyaW5ncyArIDEpOlxcbiAgICAgICAgcGhpID0gbWF0aC5waSAqIHJpIC8gcmluZ3MgICMgMCB0byBwaVxcbiAgICAgICAgcmluZyA9IFtdXFxuICAgICAgICBmb3Igc2kgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIHRoZXRhID0gbWF0aC50YXUgKiBzaSAvIHNlZ21lbnRzXFxuICAgICAgICAgICAgeCA9IHJhZGl1cyAqIG1hdGguc2luKHBoaSkgKiBtYXRoLmNvcyh0aGV0YSkgKiBzcXVhc2hbMF1cXG4gICAgICAgICAgICB5ID0gcmFkaXVzICogbWF0aC5zaW4ocGhpKSAqIG1hdGguc2luKHRoZXRhKSAqIHNxdWFzaFsxXVxcbiAgICAgICAgICAgIHogPSByYWRpdXMgKiBtYXRoLmNvcyhwaGkpICogc3F1YXNoWzJdXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoY2VudGVyWzBdICsgeCwgY2VudGVyWzFdICsgeSwgY2VudGVyWzJdICsgeikpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJpbmcpXFxuICAgIFxcbiAgICAjIENyZWF0ZSBmYWNlc1xcbiAgICBmb3IgcmkgaW4gcmFuZ2UocmluZ3MpOlxcbiAgICAgICAgZm9yIHNpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBzaiA9IChzaSArIDEpICUgc2VnbWVudHNcXG4gICAgICAgICAgICB0cnk6XFxuICAgICAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbdmVydHNfZ3JpZFtyaV1bc2ldLCB2ZXJ0c19ncmlkW3JpKzFdW3NpXSwgdmVydHNfZ3JpZFtyaSsxXVtzal0sIHZlcnRzX2dyaWRbcmldW3NqXV0pXFxuICAgICAgICAgICAgZXhjZXB0OlxcbiAgICAgICAgICAgICAgICBwYXNzXFxuICAgIHJldHVybiB2ZXJ0c19ncmlkXFxuXFxuIyBEZWxldGUgdGVtcCBvYmplY3RcXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZShib2R5LCBkb191bmxpbms9VHJ1ZSlcXG5cXG4jIEJ1aWxkIGJ1bm55IGFzIGEgdW5pb24gb2Ygc3F1YXNoZWQgc3BoZXJlc1xcbiMgVGhlIFN0YW5mb3JkIGJ1bm55IHNpdHMgY3JvdWNoZWQsIGZhY2luZyBmb3J3YXJkLCB3aXRoIGEgcm91bmRlZCBiYWNrXFxuIyBLZXkgZmVhdHVyZXM6IHJvdW5kZWQgYm9keSBtYXNzLCBoZWFkIHR1Y2tlZCBmb3J3YXJkLCBmb2xkZWQgZWFycyBhbG9uZyBiYWNrXFxuXFxuIyBNYWluIGJvZHkgbWFzcyAobGFyZ2UsIGVsb25nYXRlZCwgY3JvdWNoZWQpXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMCwgMCwgMC4xOCksIDAuMjgsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjQsIDAuOSwgMC44NSkpXFxuIyBMb3dlciBib2R5IC8gaGF1bmNoZXNcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLCAwLCAwLjA1KSwgMC4yMiwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMywgMC45NSwgMC42KSlcXG4jIEhlYWQgKGZvcndhcmQgYW5kIHNsaWdodGx5IGRvd24pXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4zMiwgMCwgMC4yOCksIDAuMTYsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjEsIDAuOSwgMC45NSkpXFxuIyBOb3NlIGFyZWFcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjQ0LCAwLCAwLjI0KSwgMC4wNywgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMCwgMC44LCAwLjgpKVxcblxcbiMgRWFycyAoZm9sZGVkIGJhY2sgYWxvbmcgdGhlIGJvZHkpIC0gdHdvIGZsYXR0ZW5lZCBlbG9uZ2F0ZWQgZm9ybXNcXG4jIExlZnQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgMC4xMCwgMC40NiksIDAuMTAsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgwLjM1LCAwLjI1LCAxLjYpKVxcbiMgUmlnaHQgZWFyXFxuYWRkX3NwaGVyZV9wYXJ0KGJtLCAoMC4wNSwgLTAuMTAsIDAuNDYpLCAwLjEwLCBzZWdtZW50cz00OCwgcmluZ3M9MjQsIHNxdWFzaD0oMC4zNSwgMC4yNSwgMS42KSlcXG5cXG4jIEZyb250IGxlZ3MvcGF3cyAoZm9sZGVkIHVuZGVyKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKDAuMjUsIDAuMDUsIDAuMCksIDAuMDgsIHNlZ21lbnRzPTMyLCByaW5ncz0xNiwgc3F1YXNoPSgxLjIsIDAuNiwgMC40KSlcXG5hZGRfc3BoZXJlX3BhcnQoYm0sICgwLjI1LCAtMC4wNSwgMC4wKSwgMC4wOCwgc2VnbWVudHM9MzIsIHJpbmdzPTE2LCBzcXVhc2g9KDEuMiwgMC42LCAwLjQpKVxcblxcbiMgQmFjayBoYXVuY2hlcyAocmFpc2VkKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAwLjEyLCAwLjEyKSwgMC4xNCwgc2VnbWVudHM9NDgsIHJpbmdzPTI0LCBzcXVhc2g9KDEuMCwgMC44LCAxLjEpKVxcbmFkZF9zcGhlcmVfcGFydChibSwgKC0wLjE1LCAtMC4xMiwgMC4xMiksIDAuMTQsIHNlZ21lbnRzPTQ4LCByaW5ncz0yNCwgc3F1YXNoPSgxLjAsIDAuOCwgMS4xKSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuYnVubnlfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIlN0YW5mb3JkQnVubnlcXFwiLCBtZXNoKVxcbmxpbmtfb2JqKGJ1bm55X29iailcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYnVubnlfb2JqXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG4jIEFkZCByZW1lc2ggbW9kaWZpZXIgdG8gdW5pZnkgdGhlIHNlcGFyYXRlIHNwaGVyZXMgaW50byBhIHNtb290aCBzdXJmYWNlXFxuIyBVc2UgYSByZW1lc2ggdG8gYmxlbmQgdGhlIHBhcnRzXFxucmVtZXNoID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlJlbWVzaFxcXCIsICdSRU1FU0gnKVxcbnJlbWVzaC5tb2RlID0gJ1NNT09USCdcXG5yZW1lc2gudm94ZWxfc2l6ZSA9IDAuMDNcXG5yZW1lc2guYWRhcHRpdml0eSA9IDAuMDAyXFxuXFxuIyBBZGQgc3Vic3VyZiBhZnRlciByZW1lc2ggZm9yIGV4dHJhIHNtb290aG5lc3NcXG5zdWJzdXJmID0gYnVubnlfb2JqLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxuc3Vic3VyZi5sZXZlbHMgPSAxXFxuc3Vic3VyZi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbiMgU2NhbGUgdG8gc2l0IG9uIHRhYmxlIGF0IHJlYXNvbmFibGUgc2l6ZVxcbmJ1bm55X29iai5zY2FsZSA9ICgxLjAsIDEuMCwgMS4wKVxcblxcbnByaW50KFxcXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwiYnVubnlfdmVydHNcXFwiOiBsZW4obWVzaC52ZXJ0aWNlcyl9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOWQ5NThkMWRiZDBmMmJjNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiYnVubnlfdmVydHNcIjogMTAwMzJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdGFuZm9yZCBCdW5ueSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGJ1aWxkIFN1emFubmUgKEJsZW5kZXIncyBtb25rZXkgaGVhZCkgYXMgYSBidXN0LCBhbmQgdGhlIGNoZWNrZXJlZCBzcGhlcmUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvciwgTWF0cml4XFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFNVWkFOTkUg4oCUIEJsZW5kZXIncyBtb25rZXkgaGVhZCwgYXMgYSBidXN0XFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX21vbmtleV9hZGQoc2l6ZT0wLjUsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zdXphbm5lID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnN1emFubmUubmFtZSA9IFxcXCJTdXphbm5lXFxcIlxcblxcbiMgQWRkIGEgc2ltcGxlIGJ1c3QgYmFzZS9wZWRlc3RhbCB1bmRlciBTdXphbm5lXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jeWxpbmRlcl9hZGQocmFkaXVzPTAuMTIsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgwLCAwLCAtMC4xNSkpXFxuYnVzdF9iYXNlID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmJ1c3RfYmFzZS5uYW1lID0gXFxcIlN1emFubmVCYXNlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBUYXBlciB0aGUgYmFzZSBzbGlnaHRseSAoY2xhc3NpY2FsIGJ1c3QgcGVkZXN0YWwpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGJ1c3RfYmFzZVxcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTMpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG4jIFNjYWxlIHRvcCB2ZXJ0aWNlcyBzbGlnaHRseVxcbm1lc2ggPSBidXN0X2Jhc2UuZGF0YVxcbmZvciB2IGluIG1lc2gudmVydGljZXM6XFxuICAgIGlmIHYuY28ueiA+IDAuMDQ6XFxuICAgICAgICB2LmNvLnggKj0gMC43XFxuICAgICAgICB2LmNvLnkgKj0gMC43XFxuXFxuIyBQYXJlbnQgYmFzZSB0byBTdXphbm5lIGZvciBub3dcXG5idXN0X2Jhc2UucGFyZW50ID0gc3V6YW5uZVxcbmJ1c3RfYmFzZS5tYXRyaXhfcGFyZW50X2ludmVyc2UgPSBzdXphbm5lLm1hdHJpeF93b3JsZC5pbnZlcnRlZCgpXFxuXFxucHJpbnQoXFxcIlN1emFubmUgYW5kIGJ1c3QgYmFzZSBidWlsdC5cXFwiKVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDSEVDS0VSRUQgU1BIRVJFIOKAlCByYXktdHJhY2luZyBkZW1vIGNsYXNzaWNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfdXZfc3BoZXJlX2FkZChyYWRpdXM9MC4yMiwgc2VnbWVudHM9NjQsIHJpbmdfY291bnQ9MzIsIGxvY2F0aW9uPSgwLCAwLCAwKSlcXG5zcGhlcmUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuc3BoZXJlLm5hbWUgPSBcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBBZGQgc3Vic3VyZiBmb3IgcGVyZmVjdGx5IHNtb290aCBzcGhlcmVcXG5tb2QgPSBzcGhlcmUubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QubGV2ZWxzID0gMVxcbm1vZC5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnByaW50KFxcXCJDaGVja2VyZWQgc3BoZXJlIGJ1aWx0LlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX3ZlcnRzXFxcIjogbGVuKHN1emFubmUuZGF0YS52ZXJ0aWNlcyksIFxcXCJzcGhlcmVfdmVydHNcXFwiOiBsZW4oc3BoZXJlLmRhdGEudmVydGljZXMpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzMDI0MjA4NjMwMWM4ZTAiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN1emFubmVfdmVydHNcIjogNTA3LFxuICAgIFwic3BoZXJlX3ZlcnRzXCI6IDE5ODZcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJTdXphbm5lIGFuZCBidXN0IGJhc2UgYnVpbHQuXFxuQ2hlY2tlcmVkIHNwaGVyZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGFkZCB0aGUgc3VwcG9ydGluZyBjbGFzc2ljYWwgcHJvcHMg4oCUIEknbGwgY3JlYXRlIGEgd2luZSBnbGFzcywgYSBib29rLCBhbmQgc29tZSBmcnVpdC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjM5NDRmZjE1MTYwMDY4NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yLCBNYXRyaXhcXG5cXG5kZWYgbGlua19vYmoob2JqKTpcXG4gICAgYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsob2JqKVxcbiAgICByZXR1cm4gb2JqXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIFdJTkUgR0xBU1Mg4oCUIGNsYXNzaWNhbCBzdGlsbCBsaWZlIHByb3BcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lR2xhc3NNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSB3aW5lIGdsYXNzIChyYWRpdXMsIGhlaWdodCkg4oCUIGxhdGhlZFxcbmdsYXNzX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjAwKSwgICAgIyBiYXNlIGNlbnRlclxcbiAgICAoMC4xNCwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjE1LCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMywgMC4wMiksICAgICMgXFxuICAgICgwLjA0LCAwLjAzKSwgICAgIyBzdGVtIGJhc2VcXG4gICAgKDAuMDM1LCAwLjEwKSwgICAjIHN0ZW1cXG4gICAgKDAuMDM1LCAwLjE4KSwgICAjIHN0ZW1cXG4gICAgKDAuMDQsIDAuMjUpLCAgICAjIGJvd2wgYmFzZVxcbiAgICAoMC4wOCwgMC4zMCksICAgICMgYm93bCB3aWRlbmluZ1xcbiAgICAoMC4xMiwgMC4zNiksICAgICMgXFxuICAgICgwLjE0LCAwLjQyKSwgICAgIyBib3dsIHdpZGVzdFxcbiAgICAoMC4xMzUsIDAuNDgpLCAgICMgXFxuICAgICgwLjExLCAwLjUzKSwgICAgIyB0YXBlcmluZyBpblxcbiAgICAoMC4wOCwgMC41NyksICAgICMgXFxuICAgICgwLjA2LCAwLjYwKSwgICAgIyByaW1cXG4gICAgKDAuMDAsIDAuNjApLCAgICAjIGNlbnRlciB0b3AgKG9wZW4pXFxuXVxcblxcbnNlZ21lbnRzID0gNDhcXG5hbGxfdmVydHMgPSBbXVxcbmZvciByLCBoIGluIGdsYXNzX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSBnbGFzc19wcm9maWxlW3JpXVxcbiAgICByYiwgXyA9IGdsYXNzX3Byb2ZpbGVbcmkgKyAxXVxcbiAgICBmb3IgaSBpbiByYW5nZShzZWdtZW50cyk6XFxuICAgICAgICBqID0gKGkgKyAxKSAlIHNlZ21lbnRzXFxuICAgICAgICBpZiByYSA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXV0pXFxuICAgICAgICBlbGlmIHJiIDwgMC4wMDE6XFxuICAgICAgICAgICAgIyBEb24ndCBjYXAgdGhlIHRvcCAtIGxlYXZlIG9wZW5cXG4gICAgICAgICAgICBwYXNzXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuZ2xhc3Nfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVHbGFzc1xcXCIsIG1lc2gpXFxubGlua19vYmooZ2xhc3Nfb2JqKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBnbGFzc19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5IGZvciBnbGFzcyB0aGlja25lc3NcXG5tb2QgPSBnbGFzc19vYmoubW9kaWZpZXJzLm5ldyhcXFwiU29saWRpZnlcXFwiLCAnU09MSURJRlknKVxcbm1vZC50aGlja25lc3MgPSAwLjAwNFxcbm1vZC5vZmZzZXQgPSAxXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE9QRU4gQk9PSyDigJQgY2xhc3NpY2FsIHN0aWxsIGxpZmUgcHJvcFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBCb29rIGJhc2UgKHR3byBwYWdlcyBtZWV0aW5nIGF0IHNwaW5lKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgMCkpXFxuYm9vayA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5ib29rLm5hbWUgPSBcXFwiT3BlbkJvb2tcXFwiXFxuYm9vay5zY2FsZSA9ICgwLjQ1LCAwLjMyLCAwLjAzKVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSB0aGUgcGFnZXMgLSBjcmVhdGUgYSBWLXNoYXBlIGZvciBvcGVuIGJvb2tcXG5icHkuY29udGV4dC52aWV3X2xheWVyLm9iamVjdHMuYWN0aXZlID0gYm9va1xcbmJweS5vcHMub2JqZWN0Lm1vZGVfc2V0KG1vZGU9J0VESVQnKVxcbmJweS5vcHMubWVzaC5zZWxlY3RfYWxsKGFjdGlvbj0nU0VMRUNUJylcXG5icHkub3BzLm1lc2guc3ViZGl2aWRlKG51bWJlcl9jdXRzPTgpXFxuYnB5Lm9wcy5vYmplY3QubW9kZV9zZXQobW9kZT0nT0JKRUNUJylcXG5cXG5tZXNoID0gYm9vay5kYXRhXFxuIyBDcmVhdGUgdGhlIFYtc2hhcGU6IHNwaW5lIGluIGNlbnRlciBkaXBzIGRvd24sIGVkZ2VzIGN1cnZlIHVwIHNsaWdodGx5XFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgIyBEaXN0YW5jZSBmcm9tIGNlbnRlciBsaW5lICh4PTAgaXMgc3BpbmUpXFxuICAgIGRpc3RfZnJvbV9zcGluZSA9IGFicyh2LmNvLngpXFxuICAgICMgUGFnZXMgY3VydmUgdXAgYXQgZWRnZXNcXG4gICAgdi5jby56ICs9IDAuMDIgKiAoZGlzdF9mcm9tX3NwaW5lIC8gMC40NSkgKiogMS41XFxuICAgICMgU3BpbmUgZGlwc1xcbiAgICBpZiBkaXN0X2Zyb21fc3BpbmUgPCAwLjA1OlxcbiAgICAgICAgdi5jby56IC09IDAuMDFcXG5cXG4jIEFkZCBhIHNlY29uZCB0aGluIGN1YmUgZm9yIHRoZSBjb3ZlciAoZGFya2VyKVxcbmJweS5vcHMubWVzaC5wcmltaXRpdmVfY3ViZV9hZGQoc2l6ZT0xLCBsb2NhdGlvbj0oMCwgMCwgLTAuMDIpKVxcbmNvdmVyID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNvdmVyLm5hbWUgPSBcXFwiQm9va0NvdmVyXFxcIlxcbmNvdmVyLnNjYWxlID0gKDAuNDgsIDAuMzQsIDAuMDE1KVxcbmJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuXFxuIyBTaGFwZSBjb3ZlciB0byBtYXRjaFxcbm1lc2ggPSBjb3Zlci5kYXRhXFxuZm9yIHYgaW4gbWVzaC52ZXJ0aWNlczpcXG4gICAgZGlzdF9mcm9tX3NwaW5lID0gYWJzKHYuY28ueClcXG4gICAgdi5jby56ICs9IDAuMDIyICogKGRpc3RfZnJvbV9zcGluZSAvIDAuNDgpICoqIDEuNVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBGUlVJVCDigJQgYSBmZXcgb3Jhbmdlcy9sZW1vbnMgZm9yIGNvbG9yIGFuZCBsaWZlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5mcnVpdHMgPSBbXVxcbmZydWl0X2NvbG9ycyA9IFtcXG4gICAgKCgwLjEwLCAwLCAwKSwgMC4wOSwgXFxcIk9yYW5nZTFcXFwiKSwgICAjIG9yYW5nZSwgc2xpZ2h0IG9mZnNldFxcbiAgICAoKDAuMTgsIDAuMDgsIDApLCAwLjA3NSwgXFxcIk9yYW5nZTJcXFwiKSwgICMgb3JhbmdlLCBkaWZmZXJlbnQgcG9zaXRpb25cXG4gICAgKCgwLjAsIDAuMTIsIDApLCAwLjA4LCBcXFwiTGVtb24xXFxcIiksICAgIyBsZW1vblxcbl1cXG5cXG5mb3IgaSwgKHBvcywgcmFkaXVzLCBuYW1lKSBpbiBlbnVtZXJhdGUoZnJ1aXRfY29sb3JzKTpcXG4gICAgYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz1yYWRpdXMsIHNlZ21lbnRzPTMyLCByaW5nX2NvdW50PTE2LCBsb2NhdGlvbj1wb3MpXFxuICAgIGZydWl0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbiAgICBmcnVpdC5uYW1lID0gbmFtZVxcbiAgICAjIFNxdWFzaCBzbGlnaHRseSBmb3IgZnJ1aXQgc2hhcGVcXG4gICAgZnJ1aXQuc2NhbGUgPSAoMS4wLCAxLjAsIDAuODgpXFxuICAgIGJweS5vcHMub2JqZWN0LnRyYW5zZm9ybV9hcHBseShsb2NhdGlvbj1GYWxzZSwgcm90YXRpb249RmFsc2UsIHNjYWxlPVRydWUpXFxuICAgIGJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuICAgIGZydWl0cy5hcHBlbmQoZnJ1aXQpXFxuXFxucHJpbnQoXFxcIldpbmUgZ2xhc3MsIGJvb2ssIGFuZCBmcnVpdCBidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwib2JqZWN0c1xcXCI6IFtcXFwiV2luZUdsYXNzXFxcIiwgXFxcIk9wZW5Cb29rXFxcIiwgXFxcIkJvb2tDb3ZlclxcXCJdICsgW2YubmFtZSBmb3IgZiBpbiBmcnVpdHNdfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWIzOTQ0ZmYxNTE2MDA2ODQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIm9iamVjdHNcIjogW1xuICAgICAgXCJXaW5lR2xhc3NcIixcbiAgICAgIFwiT3BlbkJvb2tcIixcbiAgICAgIFwiQm9va0NvdmVyXCIsXG4gICAgICBcIk9yYW5nZTFcIixcbiAgICAgIFwiT3JhbmdlMlwiLFxuICAgICAgXCJMZW1vbjFcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJXaW5lIGdsYXNzLCBib29rLCBhbmQgZnJ1aXQgYnVpbHQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBwb3NpdGlvbiBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIGNvbXBvc2l0aW9uLCB0aGVuIGNyZWF0ZSBtYXRlcmlhbHMuIExldCBtZSBhcnJhbmdlIGV2ZXJ5dGhpbmcgb24gdGhlIHRhYmxlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMTFiMTFhYjBjNDYxNjk0IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ09NUE9TSVRJT046IFBvc2l0aW9uIGFsbCBvYmplY3RzIG9uIHRoZSB0YWJsZVxcbiMgQ2FtZXJhIHdpbGwgYmUgYXQgc2xpZ2h0bHktZWxldmF0ZWQgYW5nbGUsIH41MG1tIGVxdWl2YWxlbnRcXG4jIFRlYXBvdCBjb21tYW5kcyB0aGUgYXJyYW5nZW1lbnQgKGNlbnRlci1oZXJvKSwgb3RoZXJzIGdyb3VwZWQgYXJvdW5kXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIFRhYmxlIHN1cmZhY2UgaXMgYXQgej0wXFxuIyBDYW1lcmEgd2lsbCBsb29rIGZyb20gZnJvbnQtbGVmdCwgc2xpZ2h0bHkgZWxldmF0ZWRcXG5cXG4jIC0tLSBVdGFoIFRlYXBvdCAoaGVybywgY2VudGVyLCBjb21tYW5kaW5nKSAtLS1cXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoLTAuMSwgMC4xLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMjUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjg1LCAwLjg1LCAwLjg1KVxcblxcbiMgLS0tIFN0YW5mb3JkIEJ1bm55IChsZWZ0IG9mIHRlYXBvdCwgb24gZ3JlZW4gY2xvdGggYXJlYSkgLS0tXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5idW5ueS5sb2NhdGlvbiA9ICgtMS4xNSwgMC4yNSwgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcbmJ1bm55LnNjYWxlID0gKDEuMywgMS4zLCAxLjMpXFxuXFxuIyAtLS0gU3V6YW5uZSAocmlnaHQgb2YgdGVhcG90LCBhcyBidXN0IHBvcnRyYWl0IGdhemluZyBvdXQpIC0tLVxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMDUsIDAuMTgpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCBtYXRoLnJhZGlhbnMoLTEwKSwgbWF0aC5yYWRpYW5zKDcwKSlcXG5cXG4jIC0tLSBDaGVja2VyZWQgU3BoZXJlIChmcm9udC1jZW50ZXIsIGluIGZyb250IG9mIHRlYXBvdCkgLS0tXFxuc3BoZXJlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2hlY2tlcmVkU3BoZXJlXFxcIl1cXG5zcGhlcmUubG9jYXRpb24gPSAoMC4xNSwgLTAuNTUsIDAuMjIpXFxuXFxuIyAtLS0gV2luZSBHbGFzcyAocmlnaHQgc2lkZSwgYmFjaykgLS0tXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNTUsIDAuMywgMC4wKVxcbmdsYXNzLnNjYWxlID0gKDEuMSwgMS4xLCAxLjEpXFxuXFxuIyAtLS0gT3BlbiBCb29rIChsZWZ0LWZyb250LCBwYXJ0aWFsbHkgdW5kZXIgYnVubnkpIC0tLVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC42LCAtMC43LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uXFxuY292ZXIucm90YXRpb25fZXVsZXIgPSBib29rLnJvdGF0aW9uX2V1bGVyXFxuXFxuIyAtLS0gRnJ1aXQgKGNsdXN0ZXJlZCBuZWFyIGZyb250LXJpZ2h0KSAtLS1cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ubG9jYXRpb24gPSAoMC44NSwgLTAuNzUsIDAuMDkpXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygzMCkpXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMlxcXCJdLmxvY2F0aW9uID0gKDEuMDUsIC0wLjY1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgMClcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjcsIC0wLjU1LCAwLjA4KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkxlbW9uMVxcXCJdLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucygxNSksIDAsIG1hdGgucmFkaWFucyg0NSkpXFxuXFxucHJpbnQoXFxcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxcIilcXG5yZXN1bHQgPSB7by5uYW1lOiBsaXN0KG8ubG9jYXRpb24pIGZvciBvIGluIGJweS5kYXRhLm9iamVjdHMgaWYgby50eXBlID09ICdNRVNIJyBvciBvLm5hbWUgPT0gJ1V0YWhUZWFwb3QnfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWExMWIxMWFiMGM0NjE2OTQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcIkJhY2tXYWxsXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDIuNSxcbiAgICAgIDIuMFxuICAgIF0sXG4gICAgXCJCb29rQ292ZXJcIjogW1xuICAgICAgLTAuNjAwMDAwMDIzODQxODU3OSxcbiAgICAgIC0wLjY5OTk5OTk4ODA3OTA3MSxcbiAgICAgIDAuMDE5OTk5OTk5NTUyOTY1MTY0XG4gICAgXSxcbiAgICBcIkNoZWNrZXJlZFNwaGVyZVwiOiBbXG4gICAgICAwLjE1MDAwMDAwNTk2MDQ2NDQ4LFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4yMTk5OTk5OTg4MDc5MDcxXG4gICAgXSxcbiAgICBcIkZsb29yXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0zLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJHcmVlbkNsb3RoXCI6IFtcbiAgICAgIDIuMCxcbiAgICAgIDAuMzAwMDAwMDExOTIwOTI4OTYsXG4gICAgICAwLjAxOTk5OTk5OTU1Mjk2NTE2NFxuICAgIF0sXG4gICAgXCJHcmVlblBhbmVsXCI6IFtcbiAgICAgIDIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiTGVtb24xXCI6IFtcbiAgICAgIDAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgLTAuNTUwMDAwMDExOTIwOTI5LFxuICAgICAgMC4wNzk5OTk5OTgyMTE4NjA2NlxuICAgIF0sXG4gICAgXCJPcGVuQm9va1wiOiBbXG4gICAgICAtMC42MDAwMDAwMjM4NDE4NTc5LFxuICAgICAgLTAuNjk5OTk5OTg4MDc5MDcxLFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiT3JhbmdlMVwiOiBbXG4gICAgICAwLjg1MDAwMDAyMzg0MTg1NzksXG4gICAgICAtMC43NSxcbiAgICAgIDAuMDkwMDAwMDAzNTc2Mjc4NjlcbiAgICBdLFxuICAgIFwiT3JhbmdlMlwiOiBbXG4gICAgICAxLjA0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAtMC42NDk5OTk5NzYxNTgxNDIxLFxuICAgICAgMC4wNzUwMDAwMDI5ODAyMzIyNFxuICAgIF0sXG4gICAgXCJSZWRDbG90aFwiOiBbXG4gICAgICAtMi4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAtMS41LFxuICAgICAgMC4wMTk5OTk5OTk1NTI5NjUxNjRcbiAgICBdLFxuICAgIFwiUmVkUGFuZWxcIjogW1xuICAgICAgLTIuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMS43OTk5OTk5NTIzMTYyODQyLFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiU3RhbmZvcmRCdW5ueVwiOiBbXG4gICAgICAtMS4xNDk5OTk5NzYxNTgxNDIsXG4gICAgICAwLjI1LFxuICAgICAgMC4wMjk5OTk5OTkzMjk0NDc3NDZcbiAgICBdLFxuICAgIFwiU3V6YW5uZVwiOiBbXG4gICAgICAxLjAsXG4gICAgICAtMC4wNTAwMDAwMDA3NDUwNTgwNixcbiAgICAgIDAuMTgwMDAwMDA3MTUyNTU3MzdcbiAgICBdLFxuICAgIFwiU3V6YW5uZUJhc2VcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTAuMTUwMDAwMDA1OTYwNDY0NDhcbiAgICBdLFxuICAgIFwiVGFibGVFZGdlXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIC0xLjc1LFxuICAgICAgLTAuMDUwMDAwMDAwNzQ1MDU4MDZcbiAgICBdLFxuICAgIFwiVGFibGVUb3BcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEJvZHlcIjogW1xuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wXG4gICAgXSxcbiAgICBcIlRlYXBvdEhhbmRsZVwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVGVhcG90TGlkXCI6IFtcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMFxuICAgIF0sXG4gICAgXCJUZWFwb3RTcG91dFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiVXRhaFRlYXBvdFwiOiBbXG4gICAgICAtMC4xMDAwMDAwMDE0OTAxMTYxMixcbiAgICAgIDAuMTAwMDAwMDAxNDkwMTE2MTIsXG4gICAgICAwLjBcbiAgICBdLFxuICAgIFwiV2hpdGVDbG90aFwiOiBbXG4gICAgICAwLjAsXG4gICAgICAtMC4yMDAwMDAwMDI5ODAyMzIyNCxcbiAgICAgIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XG4gICAgXSxcbiAgICBcIldpbmVHbGFzc1wiOiBbXG4gICAgICAxLjU0OTk5OTk1MjMxNjI4NDIsXG4gICAgICAwLjMwMDAwMDAxMTkyMDkyODk2LFxuICAgICAgMC4wXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkFsbCBvYmplY3RzIHBvc2l0aW9uZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBjcmVhdGUgYWxsIHRoZSBtYXRlcmlhbHMuIFRoaXMgaXMgd2hlcmUgdGhlIHN0b3J5dGVsbGluZyBoYXBwZW5zIOKAlCBhZ2VkIGNlcmFtaWMsIHBhdGluYXRlZCBtZXRhbCwgdmVsdmV0IGNsb3RoLCBwb2xpc2hlZCBjaHJvbWUuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk3MWFlMDliMDljZDdjN2QiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIE1BVEVSSUFMU1xcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyAtLS0gMS4gVEVBUE9UOiBHbGF6ZWQgY2VyYW1pYyB3aXRoIHNpbHZlciBhY2NlbnRzIChWZXJtZWVyLXdvcnRoeSkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RDZXJhbWljXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjcyLCAwLjY4LCAwLjYwLCAxLjApICAjIHdhcm0gY3JlYW1cXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuMjVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbiMgQWRkIHN1YnRsZSBub2lzZSBmb3IgY2VyYW1pYyBpbXBlcmZlY3Rpb25cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIC0xMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjE1XFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG4jIENvbG9yIHZhcmlhdGlvblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgtMjAwLCAxMDApKVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC00MDAsIDEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxubm9pc2UyLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC43MCwgMC42NiwgMC41OCwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjc2LCAwLjcyLCAwLjY0LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIlRlYXBvdEJvZHlcXFwiLCBcXFwiVGVhcG90U3BvdXRcXFwiLCBcXFwiVGVhcG90SGFuZGxlXFxcIiwgXFxcIlRlYXBvdExpZFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIGlmIG9iai5kYXRhLm1hdGVyaWFsczpcXG4gICAgICAgIG9iai5kYXRhLm1hdGVyaWFsc1swXSA9IG1hdFxcbiAgICBlbHNlOlxcbiAgICAgICAgb2JqLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMi4gU1RBTkZPUkQgQlVOTlk6IEJyb256ZS9wYXRpbmF0ZWQgc2N1bHB0dXJlIG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVubnlCcm9uemVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDAsIDAuMjUsIDEuMCkgICMgYnJvbnplXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDEuMFxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zNVxcblxcbiMgUGF0aW5hIHZhcmlhdGlvbiAoZ3JlZW5pc2ggcGF0Y2hlcylcXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0yMDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MCwgMC4yNSwgMS4wKSAgIyBicm9uemVcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4zOCwgMC4yOCwgMS4wKSAgIyBwYXRpbmEgZ3JlZW5cXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgUm91Z2huZXNzIHZhcmlhdGlvblxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddKVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAtMTUwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMy5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG5pZiBidW5ueS5kYXRhLm1hdGVyaWFsczpcXG4gICAgYnVubnkuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRcXG5lbHNlOlxcbiAgICBidW5ueS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJUZWFwb3QgYW5kIGJ1bm55IG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJ0ZWFwb3RfbWF0XFxcIjogXFxcIk1fVGVhcG90Q2VyYW1pY1xcXCIsIFxcXCJidW5ueV9tYXRcXFwiOiBcXFwiTV9CdW5ueUJyb256ZVxcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTcxYWUwOWIwOWNkN2M3ZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwidGVhcG90X21hdFwiOiBcIk1fVGVhcG90Q2VyYW1pY1wiLFxuICAgIFwiYnVubnlfbWF0XCI6IFwiTV9CdW5ueUJyb256ZVwiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVGVhcG90IGFuZCBidW5ueSBtYXRlcmlhbHMgY3JlYXRlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNTA4MmNlOGMwMDliZWE3IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDMuIFNVWkFOTkU6IE1hcmJsZSBidXN0IG1hdGVyaWFsIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MywgMC43OCwgMS4wKSAgIyB3YXJtIG1hcmJsZVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtNDAwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDEuNVxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC02MDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm1peCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU1peCcsICgtMjAwLCAxMDApKVxcbm1peC5kYXRhX3R5cGUgPSAnUkdCQSdcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBtaXguaW5wdXRzWzJdKSAgIyBBXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbM10pICAjIEJcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobWl4Lm91dHB1dHNbMl0sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC44MiwgMC44MCwgMC43NSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjUsIDAuNDIsIDAuMzgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgU3VidGxlIGJ1bXBcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gODAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5pZiBzdXphbm5lLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBzdXphbm5lLmRhdGEubWF0ZXJpYWxzWzBdID0gaGlzdG9yeU1hdFxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIEJ1c3QgYmFzZSAtIGRhcmtlciBtYXJibGVcXG5tYXRfYmFzZSwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQnVzdEJhc2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMywgMC4yNywgMC4yMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYmFzZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVCYXNlXFxcIl1cXG5pZiBiYXNlLmRhdGEubWF0ZXJpYWxzOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0X2Jhc2VcXG5lbHNlOlxcbiAgICBiYXNlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXRfYmFzZSlcXG5cXG4jIC0tLSA0LiBDSEVDS0VSRUQgU1BIRVJFOiBQb2xpc2hlZCBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm4gLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9DaGVja2VyZWRTcGhlcmVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOCwgMC44LCAwLjgsIDEuMClcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWRcXG5cXG4jIENoZWNrZXIgcGF0dGVyblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMi4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDIwMCwgMCkpXFxubnQubGlua3MubmV3KGNoZWNrZXIub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNSwgMC4wNSwgMC4wNSwgMS4wKSAgIyBkYXJrIHNxdWFyZXNcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC45NSwgMC45NSwgMC45NSwgMS4wKSAgIyBsaWdodCBzcXVhcmVzXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbmlmIHNwaGVyZS5kYXRhLm1hdGVyaWFsczpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzWzBdID0gbWF0XFxuZWxzZTpcXG4gICAgc3BoZXJlLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTUwODJjZThjMDA5YmVhNyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlN1emFubmUsIGJ1c3QgYmFzZSwgYW5kIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgYSBidWcg4oCUIEkgcmVmZXJlbmNlZCBgaGlzdG9yeU1hdGAgaW5zdGVhZCBvZiBgbWF0YCBmb3IgU3V6YW5uZS4gTGV0IG1lIGZpeCB0aGF0IGFuZCBjb250aW51ZSB3aXRoIHRoZSBjbG90aCBhbmQgZW52aXJvbm1lbnQgbWF0ZXJpYWxzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iOTlkODc0Yjk4NzMxN2U5IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIEZpeCBTdXphbm5lIG1hdGVyaWFsIGFzc2lnbm1lbnRcXG5tYXRfc3V6YW5uZSA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmlmIHN1emFubmUuZGF0YS5tYXRlcmlhbHM6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHNbMF0gPSBtYXRfc3V6YW5uZVxcbmVsc2U6XFxuICAgIHN1emFubmUuZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9zdXphbm5lKVxcblxcbnByaW50KFxcXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdXphbm5lX21hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gc3V6YW5uZS5kYXRhLm1hdGVyaWFsc119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjk5ZDg3NGI5ODczMTdlOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3V6YW5uZV9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1N1emFubmVNYXJibGVcIlxuICAgIF1cbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaXhlZCBTdXphbm5lIG1hdGVyaWFsLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWE4MzdmM2JmODg2ZTJiZjMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gNS4gUkVEIFZFTFZFVCBDTE9USCAoQ29ybmVsbCByZWQpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjQ1LCAwLjA1LCAwLjA0LCAxLjApICAjIGRlZXAgQ29ybmVsbCByZWRcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbiMgVmVsdmV0IHNoZWVuIHZpYSBub2lzZVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjQwLCAwLjA0LCAwLjAzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuNTUsIDAuMDgsIDAuMDYsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ2xvdGggYnVtcCBmb3Igd2VhdmVcXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZENsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA2LiBHUkVFTiBWRUxWRVQgQ0xPVEggKENvcm5lbGwgZ3JlZW4pIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fR3JlZW5WZWx2ZXRcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDUsIDAuMzAsIDAuMDYsIDEuMCkgICMgZGVlcCBDb3JuZWxsIGdyZWVuXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydSZWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4wNCwgMC4yOCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjA4LCAwLjM1LCAwLjA4LCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjRcXG5ub2lzZTIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZTIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMjAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDcuIFdISVRFL0dSRVkgTElORU4gKG5ldXRyYWwgQ29ybmVsbCBlbGVtZW50KSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMCkgICMgd2FybSBncmV5LXdoaXRlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5ic2RmLmlucHV0c1snU3BlY3VsYXIgSU9SIExldmVsJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIwLjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjcwLCAwLjY4LCAwLjYzLCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuODAsIDAuNzgsIDAuNzMsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDE1MC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiV2hpdGVDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxucHJpbnQoXFxcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJjbG90aF9tYXRlcmlhbHNcXFwiOiBbXFxcIk1fUmVkVmVsdmV0XFxcIiwgXFxcIk1fR3JlZW5WZWx2ZXRcXFwiLCBcXFwiTV9XaGl0ZUxpbmVuXFxcIl19XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTgzN2YzYmY4ODZlMmJmMyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgNTgsIGluIDxtb2R1bGU+XFxuS2V5RXJyb3I6ICdicHlfcHJvcF9jb2xsZWN0aW9uW2tleV06IGtleSBcXFwiUmVjXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGZpeCB0aGF0IHR5cG8g4oCUIEkgdXNlZCBgUmVjYCBpbnN0ZWFkIG9mIGBGYWNgLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDUuIFJFRCBWRUxWRVQgQ0xPVEggKENvcm5lbGwgcmVkKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1JlZFZlbHZldFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC40NSwgMC4wNSwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC44NVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDQuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNDAsIDAuMDQsIDAuMDMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC41NSwgMC4wOCwgMC4wNiwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTIwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJSZWRDbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNi4gR1JFRU4gVkVMVkVUIENMT1RIIChDb3JuZWxsIGdyZWVuKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuVmVsdmV0XFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA1LCAwLjMwLCAwLjA2LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjg1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxNS4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSkgICMgRml4ZWQ6ICdGYWMnIG5vdCAnUmVjJ1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA0LCAwLjI4LCAwLjA1LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMDgsIDAuMzUsIDAuMDgsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDEyMC4wXFxubnQubGlua3MubmV3KG5vaXNlMi5vdXRwdXRzWydGYWMnXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gNy4gV0hJVEUvR1JFWSBMSU5FTiAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1doaXRlTGluZW5cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuNzMsIDAuNjgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMjAuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzAsIDAuNjgsIDAuNjMsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44MCwgMC43OCwgMC43MywgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMTUwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiQ2xvdGggbWF0ZXJpYWxzIGNyZWF0ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNsb3RoX21hdGVyaWFsc1xcXCI6IFtcXFwiTV9SZWRWZWx2ZXRcXFwiLCBcXFwiTV9HcmVlblZlbHZldFxcXCIsIFxcXCJNX1doaXRlTGluZW5cXFwiXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NWZiODJhZmY0ZjdiYzkxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjbG90aF9tYXRlcmlhbHNcIjogW1xuICAgICAgXCJNX1JlZFZlbHZldFwiLFxuICAgICAgXCJNX0dyZWVuVmVsdmV0XCIsXG4gICAgICBcIk1fV2hpdGVMaW5lblwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNsb3RoIG1hdGVyaWFscyBjcmVhdGVkLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyB0aGUgZW52aXJvbm1lbnQgYW5kIHJlbWFpbmluZyBwcm9wIG1hdGVyaWFscyDigJQgd2FsbHMsIHRhYmxlLCBmcnVpdCwgZ2xhc3MsIGJvb2suIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWI1NTJkNTFhYjA1OWE2ZTgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuXFxuZGVmIGNyZWF0ZV9tYXRlcmlhbChuYW1lKTpcXG4gICAgbWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLm5ldyhuYW1lKVxcbiAgICBtYXQudXNlX25vZGVzID0gVHJ1ZVxcbiAgICBudCA9IG1hdC5ub2RlX3RyZWVcXG4gICAgZm9yIG4gaW4gbGlzdChudC5ub2Rlcyk6XFxuICAgICAgICBudC5ub2Rlcy5yZW1vdmUobilcXG4gICAgcmV0dXJuIG1hdCwgbnRcXG5cXG5kZWYgYWRkX25vZGUobnQsIG5vZGVfdHlwZSwgbG9jYXRpb249KDAsMCkpOlxcbiAgICBuID0gbnQubm9kZXMubmV3KG5vZGVfdHlwZSlcXG4gICAgbi5sb2NhdGlvbiA9IGxvY2F0aW9uXFxuICAgIHJldHVybiBuXFxuXFxuIyAtLS0gOC4gQkFDSyBXQUxMIChkYXJrLCBhZ2VkIHBsYXN0ZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQmFja1dhbGxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMTIsIDAuMTAsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuOVxcblxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoMCwgMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbm5vaXNlLmlucHV0c1snRGV0YWlsJ10uZGVmYXVsdF92YWx1ZSA9IDYuMFxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgxMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTAsIDAuMDgsIDAuMDYsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xNiwgMC4xMywgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4zXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMzAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJhY2tXYWxsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSA5LiBSRUQgUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9SZWRQYW5lbFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wNCwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDEwLiBHUkVFTiBQQU5FTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0dyZWVuUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMDQsIDAuMjIsIDAuMDUsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmIG9ianNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgLS0tIDExLiBUQUJMRSBUT1AgKGFnZWQgd29vZCkgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UYWJsZVRvcFxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4yMCwgMC4xNCwgMC4wOCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42XFxuXFxuIyBXb29kIGdyYWluXFxud2F2ZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleFdhdmUnLCAoMCwgMTAwKSlcXG53YXZlLndhdmVfdHlwZSA9ICdCQU5EUydcXG53YXZlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxud2F2ZS5pbnB1dHNbJ0Rpc3RvcnRpb24nXS5kZWZhdWx0X3ZhbHVlID0gOC4wXFxud2F2ZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA0LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC4xNSwgMC4xMCwgMC4wNSwgMS4wKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjE4LCAwLjEwLCAxLjApXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAub3V0cHV0c1snQ29sb3InXSwgYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXSlcXG5cXG5idW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnVtcCcsICgxMDAsIC0xMDApKVxcbmJ1bXAuaW5wdXRzWydTdHJlbmd0aCddLmRlZmF1bHRfdmFsdWUgPSAwLjJcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJUYWJsZVRvcFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyBUYWJsZSBlZGdlIGFuZCBmbG9vciBzaGFyZSB0YWJsZSBtYXRlcmlhbFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iNTUyZDUxYWIwNTlhNmU4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA1OVxcbiAgICBudC5saW5rcy5uZXcoYnNkZiBvYmpzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG4gICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl5eXFxuU3ludGF4RXJyb3I6IGludmFsaWQgc3ludGF4LiBQZXJoYXBzIHlvdSBmb3Jnb3QgYSBjb21tYT9cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIDguIEJBQ0sgV0FMTCAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0JhY2tXYWxsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg2MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgzMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjEwLCAwLjA4LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjlcXG5cXG5ub2lzZSA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKDAsIDEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5ub2lzZS5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA2LjBcXG5jb2xvcl9yYW1wID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVmFsVG9SR0InLCAoMTAwLCAxMDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcC5pbnB1dHNbJ0ZhYyddKVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjEwLCAwLjA4LCAwLjA2LCAxLjApXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuMTYsIDAuMTMsIDAuMTAsIDEuMClcXG5udC5saW5rcy5uZXcoY29sb3JfcmFtcC5vdXRwdXRzWydDb2xvciddLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuM1xcbm5vaXNlMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVRleE5vaXNlJywgKC0xMDAsIC0xMDApKVxcbm5vaXNlMi5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMwLjBcXG5udC5saW5rcy5uZXcobm9pc2UyLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJCYWNrV2FsbFxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gOS4gUkVEIFBBTkVMIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkUGFuZWxcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDIwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMzUsIDAuMDQsIDAuMDMsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMC4gR1JFRU4gUEFORUwgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9HcmVlblBhbmVsXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA0LCAwLjIyLCAwLjA1LCAxLjApXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjdcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJHcmVlblBhbmVsXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSAxMS4gVEFCTEUgVE9QIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fVGFibGVUb3BcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuMjAsIDAuMTQsIDAuMDgsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuNlxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKDAsIDEwMCkpXFxud2F2ZS53YXZlX3R5cGUgPSAnQkFORFMnXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDguMFxcbndhdmUuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcod2F2ZS5vdXRwdXRzWydDb2xvciddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMTUsIDAuMTAsIDAuMDUsIDEuMClcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4yNSwgMC4xOCwgMC4xMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubnQubGlua3MubmV3KHdhdmUub3V0cHV0c1snQ29sb3InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiVGFibGVUb3BcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIlRhYmxlRWRnZVxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fVGFibGVUb3BcXFwiXSlcXG5cXG4jIC0tLSAxMi4gRkxPT1IgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9GbG9vclxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wOCwgMC4wNiwgMC4wNCwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC45XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiRmxvb3JcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJFbnZpcm9ubWVudCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZDdjNmFlYmQxODJhNjYyIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiRW52aXJvbm1lbnQgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTE1MDU3MzQ2ZGY4ZTEwOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIC0tLSAxMy4gV0lORSBHTEFTUyAoZ2xhc3Mgd2l0aCB3aW5lKSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX1dpbmVHbGFzc1xcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5nbGFzcyA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZHbGFzcycsICgzMDAsIDApKVxcbmdsYXNzLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuOTUsIDAuOTgsIDAuOTUsIDEuMClcXG5nbGFzcy5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjBcXG5nbGFzcy5pbnB1dHNbJ0lPUiddLmRlZmF1bHRfdmFsdWUgPSAxLjQ1XFxubnQubGlua3MubmV3KGdsYXNzLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTQuIEJPT0sgUEFHRVMgKGFnZWQgcGFwZXIpIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va1BhZ2VzXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgwLCAwLjc0LCAwLjU4LCAxLjApICAjIGFnZWQgcGFwZXJcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuODVcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTUuIEJPT0sgQ09WRVIgKGFnZWQgbGVhdGhlciAtIGRhcmspIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQm9va0NvdmVyXFxcIilcXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg0MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICgyMDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjEyLCAwLjA2LCAwLjAzLCAxLjApICAjIGRhcmsgbGVhdGhlclxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC42NVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTYuIE9SQU5HRVMgLS0tXFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9PcmFuZ2VcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNzUsIDAuMzIsIDAuMDYsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbiMgT3JhbmdlIHBlZWwgdGV4dHVyZVxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNVxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA2MC4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMi4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5mb3IgbmFtZSBpbiBbXFxcIk9yYW5nZTFcXFwiLCBcXFwiT3JhbmdlMlxcXCJdOlxcbiAgICBicHkuZGF0YS5vYmplY3RzW25hbWVdLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChtYXQpXFxuXFxuIyAtLS0gMTcuIExFTU9OIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fTGVtb25cXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuODAsIDAuNjUsIDAuMTIsIDEuMClcXG5ic2RmLmlucHV0c1snUm91Z2huZXNzJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcblxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDEwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuNFxcbm5vaXNlID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4MC4wXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0InXSwgYnVtcC5pbnB1dHNbJ0hlaWdodCddKVxcbm50LmxpbmtzLm5ldyhidW1wLm91dHB1dHNbJ05vcm1hbCddLCBic2RmLmlucHV0c1snTm9ybWFsJ10pXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiTGVtb24xXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG5wcmludChcXFwiUHJvcCBtYXRlcmlhbHMgY3JlYXRlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcIm1hdGVyaWFsc1xcXCI6IFttLm5hbWUgZm9yIG0gaW4gYnB5LmRhdGEubWF0ZXJpYWxzXX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMTUwNTczNDZkZjhlMTA4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJlcnJvclwiLFxuICBcIm1lc3NhZ2VcIjogXCJUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6XFxuICBGaWxlIFxcXCJDOlxcXFxVc2Vyc1xcXFxwcm91ZFxcXFxEb3dubG9hZHNcXFxcVGVsZWdyYW0gRGVza3RvcFxcXFxibGVuZGVyLWJlbmNoLXJ1bm5lci13aW5kb3dzXFxcXC5ydW5uZXJcXFxcYmxlbmRlci1tY3AtdjEuMC4wXFxcXGFkZG9uXFxcXG1jcF90b19ibGVuZGVyX3NlcnZlci5weVxcXCIsIGxpbmUgMjMwLCBpbiBfZXhlY3V0ZV9jb2RlXFxuICAgIGV4ZWMoY29kZSwgbmFtZXNwYWNlKVxcbiAgICB+fn5+Xl5eXl5eXl5eXl5eXl5eXl5cXG4gIEZpbGUgXFxcIjxzdHJpbmc+XFxcIiwgbGluZSA3NywgaW4gPG1vZHVsZT5cXG5LZXlFcnJvcjogJ2JweV9wcm9wX2NvbGxlY3Rpb25ba2V5XToga2V5IFxcXCJCXFxcIiBub3QgZm91bmQnXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYjI5YTJmZTVjNDExZDVhOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbGVtb24gbWF0ZXJpYWwgLSB0aGUgbm9pc2Ugb3V0cHV0IHNob3VsZCBiZSAnRmFjJyBub3QgJ0InXFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9MZW1vblxcXCIpXFxuaWYgbWF0OlxcbiAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jIFJlLWNyZWF0ZSBsZW1vbiB3aXRoIGNvcnJlY3Qgb3V0cHV0XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9MZW1vblxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44MCwgMC42NSwgMC4xMiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC43XFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC40XFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMTAwLCAtMTAwKSlcXG5ub2lzZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDgwLjBcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSkgICMgRml4ZWQ6ICdGYWMnXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJMZW1vbiBtYXRlcmlhbCBmaXhlZC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iMjlhMmZlNWM0MTFkNWE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGVtb24gbWF0ZXJpYWwgZml4ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBzZXQgdXAgdGhlIGxpZ2h0aW5nIOKAlCB0aGUgY2hpYXJvc2N1cm8gc2hhZnQgb2Ygd2FybSBsaWdodC4gVGhlbiB0aGUgY2FtZXJhLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iMGQ3ODFkZDlkYzk2NDA1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBMSUdIVElORzogQ2hpYXJvc2N1cm8g4oCUIHNpbmdsZSB3YXJtIHNoYWZ0IG9mIGxpZ2h0IGZyb20gb25lIHNpZGVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIEtleSBsaWdodDogd2FybSB3aW5kb3cgc2hhZnQgZnJvbSB0aGUgbGVmdCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMy4wLCAtMS4wLCAzLjUpKVxcbmtleV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5rZXlfbGlnaHQubmFtZSA9IFxcXCJLZXlMaWdodF9XYXJtU2hhZnRcXFwiXFxua2V5X2xpZ2h0LmRhdGEuZW5lcmd5ID0gODAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjg1LCAwLjYpICAjIHdhcm0gdHVuZ3N0ZW5cXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMi4wXFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMy41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1MCksIG1hdGgucmFkaWFucygtMjApLCBtYXRoLnJhZGlhbnMoMjApKVxcblxcbiMgLS0tIEZpbGwgbGlnaHQ6IHZlcnkgZGltIGNvb2wgZmlsbCBmcm9tIHJpZ2h0IChqdXN0IHRvIGxpZnQgc2hhZG93cyBzbGlnaHRseSkgLS0tXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy4wLCAwLjUsIDIuNSkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0Nvb2xcXFwiXFxuZmlsbF9saWdodC5kYXRhLmVuZXJneSA9IDMwXFxuZmlsbF9saWdodC5kYXRhLmNvbG9yID0gKDAuNiwgMC43LCAwLjkpICAjIGNvb2wgYmx1ZVxcbmZpbGxfbGlnaHQuZGF0YS5zaXplID0gMy4wXFxuZmlsbF9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoNjApLCBtYXRoLnJhZGlhbnMoMjApLCBtYXRoLnJhZGlhbnMoLTMwKSlcXG5cXG4jIC0tLSBSaW0gbGlnaHQ6IHN1YnRsZSB3YXJtIHJpbSBmcm9tIGJlaGluZCB0byBzZXBhcmF0ZSBvYmplY3RzIGZyb20gYmFja2dyb3VuZCAtLS1cXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nU1BPVCcsIGxvY2F0aW9uPSgwLCAyLjUsIDIuNSkpXFxucmltX2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbnJpbV9saWdodC5uYW1lID0gXFxcIlJpbUxpZ2h0XFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDEwMFxcbnJpbV9saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44LCAwLjUpXFxucmltX2xpZ2h0LmRhdGEuc3BvdF9zaXplID0gbWF0aC5yYWRpYW5zKDYwKVxcbnJpbV9saWdodC5kYXRhLnNwb3RfYmxlbmQgPSAwLjhcXG5yaW1fbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDEyMCksIDAsIDApXFxuXFxuIyAtLS0gV2luZG93IGZyYW1lIGxpZ2h0IChjcmVhdGVzIHRoZSBzaGFmdCBwYXR0ZXJuKSAtLS1cXG4jIEEgbmFycm93IGFyZWEgbGlnaHQgdG8gc2ltdWxhdGUgbGlnaHQgY29taW5nIHRocm91Z2ggYSB3aW5kb3dcXG5icHkub3BzLm9iamVjdC5saWdodF9hZGQodHlwZT0nQVJFQScsIGxvY2F0aW9uPSgtMi41LCAwLjUsIDIuOCkpXFxud2luZG93X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbndpbmRvd19saWdodC5uYW1lID0gXFxcIldpbmRvd0xpZ2h0XFxcIlxcbndpbmRvd19saWdodC5kYXRhLmVuZXJneSA9IDQwMFxcbndpbmRvd19saWdodC5kYXRhLmNvbG9yID0gKDEuMCwgMC44OCwgMC42NSlcXG53aW5kb3dfbGlnaHQuZGF0YS5zaXplID0gMC44XFxud2luZG93X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMS41XFxud2luZG93X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMTUpKVxcblxcbnByaW50KFxcXCJMaWdodGluZyBzZXQgdXAuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjBkNzgxZGQ5ZGM5NjQwNSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0Nvb2xcIixcbiAgICAgIFwiS2V5TGlnaHRfV2FybVNoYWZ0XCIsXG4gICAgICBcIlJpbUxpZ2h0XCIsXG4gICAgICBcIldpbmRvd0xpZ2h0XCJcbiAgICBdXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiTGlnaHRpbmcgc2V0IHVwLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6Ik5vdyBsZXQgbWUgc2V0IHVwIHRoZSBjYW1lcmEgYXQgdGhlIGludGltYXRlIHNsaWdodGx5LWVsZXZhdGVkIGFuZ2xlIG9mIHRoZSBnZW5yZSwgcm91Z2hseSA1MG1tIGVxdWl2YWxlbnQuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgxZDUxNGY1ZjIxMmMxZmUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBDQU1FUkE6IH41MG1tIGVxdWl2YWxlbnQsIHNsaWdodGx5IGVsZXZhdGVkIGludGltYXRlIGFuZ2xlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5icHkub3BzLm9iamVjdC5jYW1lcmFfYWRkKGxvY2F0aW9uPSgzLjIsIC0zLjgsIDIuMikpXFxuY2FtID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmNhbS5uYW1lID0gXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXFxuY2FtLmRhdGEubGVucyA9IDUwICAjIDUwbW0gZm9jYWwgbGVuZ3RoXFxuY2FtLmRhdGEuc2Vuc29yX3dpZHRoID0gMzYgICMgZnVsbCBmcmFtZVxcbmNhbS5kYXRhLnNlbnNvcl9oZWlnaHQgPSAzNiAgIyBzcXVhcmUgZm9ybWF0IGZvciAxNTM2eDE1MzZcXG5cXG4jIFBvaW50IGNhbWVyYSBhdCB0aGUgdGVhcG90IChjZW50ZXIgb2YgYXJyYW5nZW1lbnQpXFxudGFyZ2V0ID0gVmVjdG9yKCgtMC4xLCAwLjEsIDAuNCkpICAjIHNsaWdodGx5IGFib3ZlIHRhYmxlLCBhdCB0ZWFwb3QgaGVpZ2h0XFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxuIyBDb252ZXJ0IGRpcmVjdGlvbiB0byByb3RhdGlvblxcbnJvdF9xdWF0ID0gZGlyZWN0aW9uLnRvX3RyYWNrX3F1YXQoJy1aJywgJ1knKVxcbmNhbS5yb3RhdGlvbl9ldWxlciA9IHJvdF9xdWF0LnRvX2V1bGVyKClcXG5cXG4jIFNldCBhcyBhY3RpdmUgc2NlbmUgY2FtZXJhXFxuYnB5LmNvbnRleHQuc2NlbmUuY2FtZXJhID0gY2FtXFxuXFxuIyBEZXB0aCBvZiBmaWVsZCAtIHN1YnRsZSwgZm9jdXNlZCBvbiB0ZWFwb3RcXG5jYW0uZGF0YS5kb2YudXNlX2RvZiA9IFRydWVcXG5jYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2UgPSAoY2FtLmxvY2F0aW9uIC0gdGFyZ2V0KS5sZW5ndGhcXG5jYW0uZGF0YS5kb2YuYXBlcnR1cmVfZnN0b3AgPSA0LjBcXG5cXG5wcmludChcXFwiQ2FtZXJhIHNldCB1cC5cXFwiKVxcbnJlc3VsdCA9IHtcXG4gICAgXFxcImNhbWVyYV9sb2NhdGlvblxcXCI6IGxpc3QoY2FtLmxvY2F0aW9uKSxcXG4gICAgXFxcImNhbWVyYV9yb3RhdGlvblxcXCI6IFttYXRoLmRlZ3JlZXMocikgZm9yIHIgaW4gY2FtLnJvdGF0aW9uX2V1bGVyXSxcXG4gICAgXFxcImxlbnNcXFwiOiBjYW0uZGF0YS5sZW5zLFxcbiAgICBcXFwiZm9jdXNfZGlzdGFuY2VcXFwiOiBjYW0uZGF0YS5kb2YuZm9jdXNfZGlzdGFuY2VcXG59XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFkNTE0ZjVmMjEyYzFmZSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwiY2FtZXJhX2xvY2F0aW9uXCI6IFtcbiAgICAgIDMuMjAwMDAwMDQ3NjgzNzE2LFxuICAgICAgLTMuNzk5OTk5OTUyMzE2Mjg0LFxuICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICBdLFxuICAgIFwiY2FtZXJhX3JvdGF0aW9uXCI6IFtcbiAgICAgIDcwLjU5MTAwOTEwOTg4OTc3LFxuICAgICAgLTEuMDc5NTgyODUwODYwNTIyOGUtNixcbiAgICAgIDQwLjIzNjM2NDM2Mjc4OTE0NlxuICAgIF0sXG4gICAgXCJsZW5zXCI6IDUwLjAsXG4gICAgXCJmb2N1c19kaXN0YW5jZVwiOiA1LjQxNjY0MDc1ODUxNDQwNFxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbWVyYSBzZXQgdXAuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIGRvIGEgcXVpY2sgcmVuZGVyIHByZXZpZXcgdG8gc2VlIHdoZXJlIHdlIGFyZSwgdGhlbiBJJ2xsIHJlZmluZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODBhMDMyYjEzM2ZlYzYxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJyZW5kZXJfdGh1bWJuYWlsX3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgwYTAzMmIxMzNmZWM2MTgiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJmaWxlcGF0aFwiOiBcIkM6XFxcXFVzZXJzXFxcXHByb3VkXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcVGVtcFxcXFxibGVuZGVyX2E4NzIwNFxcXFxibGVuZGVyX21jcFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTExMDdjMjc1NzNjYjQyMSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkxMTA3YzI3NTczY2I0MjEiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBsb29rIGF0IHRoZSByZW5kZXJlZCBpbWFnZSB0byBldmFsdWF0ZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTdjN2I1NTQ2YTFhZDc5MiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBDaGVjayB3aGF0IHRoZSByZW5kZXIgb3V0cHV0IGxvb2tzIGxpa2UgYnkgZXhhbWluaW5nIHRoZSBpbWFnZVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3ByZXZpZXcxLnBuZ1xcXCIpXFxucHJpbnQoZlxcXCJJbWFnZSBzaXplOiB7aW1nLnNpemVbMF19eHtpbWcuc2l6ZVsxXX1cXFwiKVxcbnByaW50KGZcXFwiSW1hZ2UgY2hhbm5lbHM6IHtpbWcuY2hhbm5lbHN9XFxcIilcXG4jIEdldCBzb21lIHBpeGVsIHZhbHVlcyB0byBjaGVjayBpZiBpdCdzIHJlbmRlcmluZyBwcm9wZXJseVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVsc1s6MjBdKVxcbnByaW50KGZcXFwiRmlyc3QgcGl4ZWxzOiB7cGl4ZWxzfVxcXCIpXFxucmVzdWx0ID0ge1xcXCJpbWFnZV9zaXplXFxcIjogbGlzdChpbWcuc2l6ZSksIFxcXCJsb2FkZWRcXFwiOiBUcnVlfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTk3YzdiNTU0NmExYWQ3OTIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcImltYWdlX3NpemVcIjogW1xuICAgICAgMTUzNixcbiAgICAgIDE1MzZcbiAgICBdLFxuICAgIFwibG9hZGVkXCI6IHRydWVcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJJbWFnZSBzaXplOiAxNTM2eDE1MzZcXG5JbWFnZSBjaGFubmVsczogNFxcbkZpcnN0IHBpeGVsczogWzAuMjU0OTAxOTc1MzkzMjk1MywgMC4yMDAwMDAwMTc4ODEzOTM0MywgMC4xNTY4NjI3NTA2NDk0NTIyLCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAwMDAwMDE3ODgxMzkzNDMsIDAuMTQxMTc2NDc3MDc0NjIzMSwgMS4wLCAwLjI3NDUwOTgxNzM2MTgzMTY3LCAwLjIwMDAwMDAxNzg4MTM5MzQzLCAwLjEzMzMzMzM0MDI4NzIwODU2LCAxLjAsIDAuMjc0NTA5ODE3MzYxODMxNjcsIDAuMjAzOTIxNTg2Mjc1MTAwNywgMC4xMzcyNTQ5MDg2ODA5MTU4MywgMS4wLCAwLjI3ODQzMTM4NTc1NTUzODk0LCAwLjE5NjA3ODQ0OTQ4NzY4NjE2LCAwLjEyOTQxMTc3MTg5MzUwMTI4LCAxLjBdXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImFyZ3VtZW50cyI6Int9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTc1MjRjNDhhY2FjNjg2NyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcIndpbmRvd193aWR0aFwiOiAxOTIwLFxuICAgIFwid2luZG93X2hlaWdodFwiOiAxMTExLFxuICAgIFwic2NyZWVuX25hbWVcIjogXCJMYXlvdXRcIixcbiAgICBcIndvcmtzcGFjZVwiOiBcIkxheW91dFwiLFxuICAgIFwic2NlbmVcIjogXCJTY2VuZVwiLFxuICAgIFwiYXJlYXNcIjogW1xuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJQUk9QRVJUSUVTXCIsXG4gICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICBcInlcIjogMjksXG4gICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICBcImhlaWdodFwiOiA4NTQsXG4gICAgICAgIFwic3BhY2VcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcIlBST1BFUlRJRVNcIixcbiAgICAgICAgICBcImNvbnRleHRcIjogXCJPQkpFQ1RcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODUxLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiTkFWSUdBVElPTl9CQVJcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc5LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzNixcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDgyMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMTYxNSxcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzAzLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogODIyXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJPVVRMSU5FUlwiLFxuICAgICAgICBcInhcIjogMTU3OSxcbiAgICAgICAgXCJ5XCI6IDg4NixcbiAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgIFwiaGVpZ2h0XCI6IDE5MixcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiT1VUTElORVJcIixcbiAgICAgICAgICBcImRpc3BsYXlfbW9kZVwiOiBcIlZJRVdfTEFZRVJcIlxuICAgICAgICB9LFxuICAgICAgICBcInJlZ2lvbnNcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkhFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogMTA0NixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMzM5LFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMzJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIldJTkRPV1wiLFxuICAgICAgICAgICAgXCJ4XCI6IDE1NzksXG4gICAgICAgICAgICBcInlcIjogODg2LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAzMzksXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxNjBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwidHlwZVwiOiBcIkRPUEVTSEVFVF9FRElUT1JcIixcbiAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgXCJ3aWR0aFwiOiAxNTc0LFxuICAgICAgICBcImhlaWdodFwiOiA3NSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiRE9QRVNIRUVUX0VESVRPUlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicmVnaW9uc1wiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiSEVBREVSXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiA3MixcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDMyXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJGT09URVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQ0hBTk5FTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVUlcIixcbiAgICAgICAgICAgIFwieFwiOiAxNTc1LFxuICAgICAgICAgICAgXCJ5XCI6IDI5LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiV0lORE9XXCIsXG4gICAgICAgICAgICBcInhcIjogMixcbiAgICAgICAgICAgIFwieVwiOiAyOSxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDQzXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcInR5cGVcIjogXCJWSUVXXzNEXCIsXG4gICAgICAgIFwieFwiOiAyLFxuICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDk3MSxcbiAgICAgICAgXCJzcGFjZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVklFV18zRFwiLFxuICAgICAgICAgIFwidmlld19wZXJzcGVjdGl2ZVwiOiBcIlBFUlNQXCIsXG4gICAgICAgICAgXCJ2aWV3X2xvY2F0aW9uXCI6IFtcbiAgICAgICAgICAgIC0wLjAyMDY5MzI0ODEzNzgzMTY4OCxcbiAgICAgICAgICAgIC0wLjA0NjAyNTQ2OTg5OTE3NzU1LFxuICAgICAgICAgICAgMC4wMDA2Njk0MzA3NjY3MjAzMjQ4XG4gICAgICAgICAgXSxcbiAgICAgICAgICBcInNoYWRpbmdfdHlwZVwiOiBcIlNPTElEXCIsXG4gICAgICAgICAgXCJzaG93X292ZXJsYXlzXCI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgXCJyZWdpb25zXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNDYsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTF9IRUFERVJcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwMTQsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDE1NzQsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAzMlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiQVNTRVRfU0hFTEZcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMSxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDFcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIkFTU0VUX1NIRUxGX0hFQURFUlwiLFxuICAgICAgICAgICAgXCJ4XCI6IDIsXG4gICAgICAgICAgICBcInlcIjogMTA3LFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiAxLFxuICAgICAgICAgICAgXCJoZWlnaHRcIjogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwiVE9PTFNcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogNzAsXG4gICAgICAgICAgICBcImhlaWdodFwiOiA5MDdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwidHlwZVwiOiBcIlVJXCIsXG4gICAgICAgICAgICBcInhcIjogMTU3NSxcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJIVURcIixcbiAgICAgICAgICAgIFwieFwiOiA3MixcbiAgICAgICAgICAgIFwieVwiOiAxMDcsXG4gICAgICAgICAgICBcIndpZHRoXCI6IDEsXG4gICAgICAgICAgICBcImhlaWdodFwiOiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJXSU5ET1dcIixcbiAgICAgICAgICAgIFwieFwiOiAyLFxuICAgICAgICAgICAgXCJ5XCI6IDEwNyxcbiAgICAgICAgICAgIFwid2lkdGhcIjogMTU3NCxcbiAgICAgICAgICAgIFwiaGVpZ2h0XCI6IDk3MVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgXCJhY3RpdmVfb2JqZWN0XCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgIFwidHlwZVwiOiBcIkNBTUVSQVwiLFxuICAgICAgXCJtb2RlXCI6IFwiT0JKRUNUXCIsXG4gICAgICBcImxvY2F0aW9uXCI6IFtcbiAgICAgICAgMy4yMDAwMDAwNDc2ODM3MTYsXG4gICAgICAgIC0zLjc5OTk5OTk1MjMxNjI4NCxcbiAgICAgICAgMi4yMDAwMDAwNDc2ODM3MTZcbiAgICAgIF1cbiAgICB9LFxuICAgIFwic2VsZWN0ZWRfb2JqZWN0c1wiOiBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIkNhbWVyYV9QcmVzZW50YXRpb25cIixcbiAgICAgICAgXCJ0eXBlXCI6IFwiQ0FNRVJBXCJcbiAgICAgIH1cbiAgICBdLFxuICAgIFwibWVzc2FnZVwiOiBudWxsXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTGV0IG1lIHN3aXRjaCB0byB0aGUgcmVuZGVyZWQgdmlldyB0byBzZWUgdGhlIG91dHB1dC4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuIyBTZXQgdmlld3BvcnQgdG8gcmVuZGVyZWQgbW9kZSB0byBzZWUgdGhlIHJlc3VsdFxcbmZvciBhcmVhIGluIGJweS5jb250ZXh0LnNjcmVlbi5hcmVhczpcXG4gICAgaWYgYXJlYS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgIGZvciBzcGFjZSBpbiBhcmVhLnNwYWNlczpcXG4gICAgICAgICAgICBpZiBzcGFjZS50eXBlID09ICdWSUVXXzNEJzpcXG4gICAgICAgICAgICAgICAgc3BhY2Uuc2hhZGluZy50eXBlID0gJ1JFTkRFUkVEJ1xcbiAgICAgICAgICAgICAgICBicmVha1xcbiAgICAgICAgYnJlYWtcXG5wcmludChcXFwiU2V0IHZpZXdwb3J0IHRvIHJlbmRlcmVkXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOGU0YzY0NmY2ZjVlYWNhNCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlNldCB2aWV3cG9ydCB0byByZW5kZXJlZFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg3OWEwMWFmMTViMWRhNjUiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NzlhMDFhZjE1YjFkYTY1IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJMZXQgbWUgZXhhbWluZSB0aGUgcmVuZGVyZWQgcHJldmlldyBtb3JlIGNsb3NlbHkgYnkgc2FtcGxpbmcgcGl4ZWwgdmFsdWVzIGFjcm9zcyB0aGUgaW1hZ2UgdG8gdW5kZXJzdGFuZCB0aGUgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFjM2ZhN2U1YjlkMDliOGIiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5nZXQoXFxcInN0aWxsX2xpZmVfcHJldmlldzEucG5nXFxcIilcXG5pZiBpbWcgaXMgTm9uZTpcXG4gICAgIyBMb2FkIHRoZSByZW5kZXJlZCBpbWFnZVxcbiAgICBpbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzpcXFxcXFxcXFVzZXJzXFxcXFxcXFxwcm91ZFxcXFxcXFxcQXBwRGF0YVxcXFxcXFxcTG9jYWxcXFxcXFxcXFRlbXBcXFxcXFxcXGJsZW5kZXJfYTg3MjA0XFxcXFxcXFxibGVuZGVyX21jcFxcXFxcXFxcc3RpbGxfbGlmZV9wcmV2aWV3MS5wbmdcXFwiKVxcblxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBTYW1wbGUgdmFyaW91cyByZWdpb25zIG9mIHRoZSBpbWFnZVxcbmRlZiBzYW1wbGVfcmVnaW9uKHhfc3RhcnQsIHlfc3RhcnQsIHhfZW5kLCB5X2VuZCwgbGFiZWwpOlxcbiAgICByX3N1bSwgZ19zdW0sIGJfc3VtLCBjb3VudCA9IDAsIDAsIDAsIDBcXG4gICAgZm9yIHkgaW4gcmFuZ2UoeV9zdGFydCwgeV9lbmQsIDEwKTpcXG4gICAgICAgIGZvciB4IGluIHJhbmdlKHhfc3RhcnQsIHhfZW5kLCAxMCk6XFxuICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICBnX3N1bSArPSBwaXhlbHNbaWR4KzFdXFxuICAgICAgICAgICAgYl9zdW0gKz0gcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfVxcXCIpXFxuICAgIHJldHVybiByX2F2ZywgZ19hdmcsIGJfYXZnXFxuXFxuIyBTYW1wbGUgY2VudGVyLCBjb3JuZXJzLCBhbmQgcmVnaW9uc1xcbnNhbXBsZV9yZWdpb24oMCwgMCwgdy8vNCwgaC8vNCwgXFxcIlRvcC1sZWZ0IChiZylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAzKmgvLzQsIHcsIGgsIFxcXCJCb3R0b20tcmlnaHQgKGZnKVxcXCIpXFxuc2FtcGxlX3JlZ2lvbih3Ly8zLCBoLy8zLCAyKncvLzMsIDIqaC8vMywgXFxcIkNlbnRlciAob2JqZWN0cylcXFwiKVxcbnNhbXBsZV9yZWdpb24oMCwgMypoLy80LCB3Ly80LCBoLCBcXFwiQm90dG9tLWxlZnRcXFwiKVxcbnNhbXBsZV9yZWdpb24oMyp3Ly80LCAwLCB3LCBoLy80LCBcXFwiVG9wLXJpZ2h0XFxcIilcXG5cXG4jIENoZWNrIG92ZXJhbGwgYnJpZ2h0bmVzc1xcbnRvdGFsX2JyaWdodCA9IHN1bShwaXhlbHNbaV0gKyBwaXhlbHNbaSsxXSArIHBpeGVsc1tpKzJdIGZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KjEwMCkpXFxucHJpbnQoZlxcXCJcXFxcbk92ZXJhbGwgYnJpZ2h0bmVzcyBzYW1wbGU6IHt0b3RhbF9icmlnaHQgLyAobGVuKHBpeGVscykvLyg0KjEwMCkgKiAzKTouM2Z9XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWMzZmE3ZTViOWQwOWI4YiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRvcC1sZWZ0IChiZyk6IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5XFxuQm90dG9tLXJpZ2h0IChmZyk6IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2XFxuQ2VudGVyIChvYmplY3RzKTogUj0wLjUxOCBHPTAuNDcwIEI9MC4zODRcXG5Cb3R0b20tbGVmdDogUj0wLjA4NCBHPTAuMDYxIEI9MC4wNTBcXG5Ub3AtcmlnaHQ6IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzXFxuXFxuT3ZlcmFsbCBicmlnaHRuZXNzIHNhbXBsZTogMC40MDdcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgcmVuZGVyIGlzIHdvcmtpbmcuIEkgY2FuIHNlZSB0aGUgZ3JlZW4gcGFuZWwgb24gdGhlIHJpZ2h0IGFuZCBvYmplY3RzIGluIHRoZSBjZW50ZXIuIExldCBtZSBkbyBhIHByb3BlciByZW5kZXIgdG8gZXZhbHVhdGUgdGhlIGZ1bGwgY29tcG9zaXRpb24uIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTkyMTQ4MDYyOGJkZDJhY2YiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJhcmd1bWVudHMiOiJ7XCJvdXRwdXRfcGF0aFwiOiBcIkM6L3RtcC9zdGlsbF9saWZlX3JlbmRlcjEucG5nXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTIxNDgwNjI4YmRkMmFjZiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIixcbiAgICBcImZpbGVwYXRoXCI6IFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcQXBwRGF0YVxcXFxMb2NhbFxcXFxUZW1wXFxcXGJsZW5kZXJfYTg3MjA0XFxcXGJsZW5kZXJfbWNwXFxcXHN0aWxsX2xpZmVfcmVuZGVyMS5wbmdcIlxuICB9XG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgbW9yZSByZWdpb25zIHRvIHVuZGVyc3RhbmQgY29tcG9zaXRpb25cXG5kZWYgc2FtcGxlX3JlZ2lvbih4X3N0YXJ0LCB5X3N0YXJ0LCB4X2VuZCwgeV9lbmQsIGxhYmVsKTpcXG4gICAgcl9zdW0sIGdfc3VtLCBiX3N1bSwgY291bnQgPSAwLCAwLCAwLCAwXFxuICAgIGZvciB5IGluIHJhbmdlKHlfc3RhcnQsIHlfZW5kLCAxMCk6XFxuICAgICAgICBmb3IgeCBpbiByYW5nZSh4X3N0YXJ0LCB4X2VuZCwgMTApOlxcbiAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgcl9zdW0gKz0gcGl4ZWxzW2lkeF1cXG4gICAgICAgICAgICAgICAgZ19zdW0gKz0gcGl4ZWxzW2lkeCsxXVxcbiAgICAgICAgICAgICAgICBiX3N1bSArPSBwaXhlbHNbaWR4KzJdXFxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgcl9hdmcgPSByX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgZ19hdmcgPSBnX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgYl9hdmcgPSBiX3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgcHJpbnQoZlxcXCJ7bGFiZWx9OiBSPXtyX2F2ZzouM2Z9IEc9e2dfYXZnOi4zZn0gQj17Yl9hdmc6LjNmfSBicmlnaHQ9e3N1bShbcl9hdmcsZ19hdmcsYl9hdmddKS8zOi4zZn1cXFwiKVxcblxcbiMgR3JpZCBzYW1wbGluZ1xcbmZvciBneSBpbiByYW5nZSg0KTpcXG4gICAgZm9yIGd4IGluIHJhbmdlKDQpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDRcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDRcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA0XFxuICAgICAgICBzYW1wbGVfcmVnaW9uKHgxLCB5MSwgeDIsIHkyLCBmXFxcIkdyaWRbe2d4fSx7Z3l9XVxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFmMzdkZjY3Mzc3MDNkNGYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmlkWzAsMF06IFI9MC4yODAgRz0wLjIxOSBCPTAuMTQ5IGJyaWdodD0wLjIxNlxcbkdyaWRbMSwwXTogUj0wLjQzMyBHPTAuMzUxIEI9MC4yNTYgYnJpZ2h0PTAuMzQ3XFxuR3JpZFsyLDBdOiBSPTAuMzk4IEc9MC40MDYgQj0wLjI0NCBicmlnaHQ9MC4zNDlcXG5HcmlkWzMsMF06IFI9MC4yMTcgRz0wLjQxMSBCPTAuMTQzIGJyaWdodD0wLjI1N1xcbkdyaWRbMCwxXTogUj0wLjgzMiBHPTAuNjI2IEI9MC41MjggYnJpZ2h0PTAuNjYyXFxuR3JpZFsxLDFdOiBSPTAuNjU4IEc9MC42MTkgQj0wLjU0NSBicmlnaHQ9MC42MDdcXG5HcmlkWzIsMV06IFI9MC40NTUgRz0wLjQwMiBCPTAuMjgxIGJyaWdodD0wLjM3OVxcbkdyaWRbMywxXTogUj0wLjMxNiBHPTAuNDY1IEI9MC4yNDQgYnJpZ2h0PTAuMzQyXFxuR3JpZFswLDJdOiBSPTAuMzM1IEc9MC4yNzQgQj0wLjIyMSBicmlnaHQ9MC4yNzZcXG5HcmlkWzEsMl06IFI9MC42MjggRz0wLjUyMCBCPTAuNDQ0IGJyaWdodD0wLjUzMVxcbkdyaWRbMiwyXTogUj0wLjQ3NSBHPTAuNDExIEI9MC4zMTIgYnJpZ2h0PTAuNDAwXFxuR3JpZFszLDJdOiBSPTAuNTU3IEc9MC40OTMgQj0wLjM4MyBicmlnaHQ9MC40NzhcXG5HcmlkWzAsM106IFI9MC4wODQgRz0wLjA2MSBCPTAuMDUwIGJyaWdodD0wLjA2NVxcbkdyaWRbMSwzXTogUj0wLjc4NiBHPTAuNTk2IEI9MC41MDggYnJpZ2h0PTAuNjMwXFxuR3JpZFsyLDNdOiBSPTAuNDI5IEc9MC4zNTkgQj0wLjI2OCBicmlnaHQ9MC4zNTJcXG5HcmlkWzMsM106IFI9MC42ODggRz0wLjYxOCBCPTAuNDk2IGJyaWdodD0wLjYwMVxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuIyBMZXQgbWUgYW5hbHl6ZSB0aGUgY29tcG9zaXRpb24gbW9yZSBjYXJlZnVsbHlcXG4jIFRoZSBncmlkIHNob3dzOiBsZWZ0IHNpZGUgaGFzIHdhcm0gbGlnaHQsIHJpZ2h0IHNpZGUgaGFzIGdyZWVuLCBjZW50ZXIgaGFzIG9iamVjdHNcXG4jIEJvdHRvbS1sZWZ0IGlzIHZlcnkgZGFyayAoZ29vZCBmb3IgY2hpYXJvc2N1cm8pXFxuIyBMZXQgbWUgY2hlY2sgaWYgb2JqZWN0cyBhcmUgdmlzaWJsZSBhbmQgd2VsbC1wbGFjZWRcXG5cXG5pbXBvcnQgYnB5XFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmdldChcXFwic3RpbGxfbGlmZV9yZW5kZXIxLnBuZ1xcXCIpXFxuaWYgaW1nIGlzIE5vbmU6XFxuICAgIGltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOlxcXFxcXFxcVXNlcnNcXFxcXFxcXHByb3VkXFxcXFxcXFxBcHBEYXRhXFxcXFxcXFxMb2NhbFxcXFxcXFxcVGVtcFxcXFxcXFxcYmxlbmRlcl9hODcyMDRcXFxcXFxcXGJsZW5kZXJfbWNwXFxcXFxcXFxzdGlsbF9saWZlX3JlbmRlcjEucG5nXFxcIilcXG5cXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ2hlY2sgZm9yIHRoZSB0ZWFwb3QgYXJlYSAoc2hvdWxkIGJlIGNlbnRlci1pc2gsIGJyaWdodCBjZXJhbWljKVxcbiMgQ2FtZXJhIGlzIGF0ICgzLjIsIC0zLjgsIDIuMikgbG9va2luZyBhdCAoLTAuMSwgMC4xLCAwLjQpXFxuIyBUZWFwb3QgaXMgYXQgd29ybGQgKC0wLjEsIDAuMSwgMCkgLSBzaG91bGQgYmUgcm91Z2hseSBjZW50ZXIgb2YgZnJhbWVcXG5cXG4jIExldCBtZSBjaGVjayBpZiB3ZSBjYW4gc2VlIGJyaWdodCBoaWdobGlnaHRzIChjZXJhbWljIHRlYXBvdClcXG5icmlnaHRfY291bnQgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuOCBhbmQgZyA+IDAuNyBhbmQgYiA+IDAuNjpcXG4gICAgICAgIGJyaWdodF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczoge2JyaWdodF9jb3VudH0gLyB7bGVuKHBpeGVscykvLzR9ICh7MTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpOi4xZn0lKVxcXCIpXFxuXFxuIyBDaGVjayBpZiB0aGUgc3BoZXJlIGlzIHZpc2libGUgKHNob3VsZCBiZSBkYXJrL2xpZ2h0IGNoZWNrZXIgcGF0dGVybilcXG4jIENoZWNrIG1pZGRsZS1ib3R0b20gYXJlYVxcbm1pZF9ib3RfYnJpZ2h0ID0gMFxcbmZvciB5IGluIHJhbmdlKGludChoKjAuNCksIGludChoKjAuNikpOlxcbiAgICBmb3IgeCBpbiByYW5nZShpbnQodyowLjQpLCBpbnQodyowLjYpKTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgbWlkX2JvdF9icmlnaHQgKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbnByaW50KGZcXFwiQ2VudGVyIGJyaWdodG5lc3MgYXZnOiB7bWlkX2JvdF9icmlnaHQgLyAoaW50KHcqMC4yKSAqIGludChoKjAuMikpOi4zZn1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIiwgXFxcImJyaWdodF9waXhlbHNfcGN0XFxcIjogMTAwKmJyaWdodF9jb3VudC8obGVuKHBpeGVscykvLzQpfVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTllOGQxYzM4NDQxMjAyODkiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gICAgXCJicmlnaHRfcGl4ZWxzX3BjdFwiOiAxMS43NDcwMjExNDUyOTA3OThcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHQgaGlnaGxpZ2h0IHBpeGVsczogMjc3MTQ3IC8gMjM1OTI5NiAoMTEuNyUpXFxuQ2VudGVyIGJyaWdodG5lc3MgYXZnOiAwLjUxOFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSByZW5kZXIgaXMgd29ya2luZyB3ZWxsLiBJIGNhbiBzZWUgYnJpZ2h0IGhpZ2hsaWdodHMgZnJvbSB0aGUgY2VyYW1pYyB0ZWFwb3QgYW5kIG9iamVjdHMgYXJlIHZpc2libGUuIExldCBtZSBub3cgbG9vayBhdCB0aGUgYWN0dWFsIHJlbmRlcmVkIGltYWdlIHRvIGV2YWx1YXRlIHRoZSBjb21wb3NpdGlvbiB2aXN1YWxseS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOGE0MzVjYmJmNGQ2ZGRhMCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLThhNDM1Y2JiZjRkNmRkYTAiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBjaGVjayB0aGUgbW9kaWZpZXIgc3RhY2sgb24gdGhlIGJ1bm55IGFuZCB2ZXJpZnkgYWxsIG9iamVjdHMgYXJlIHJlbmRlcmluZyBwcm9wZXJseSwgdGhlbiBtYWtlIHJlZmluZW1lbnRzLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIGFsbCBvYmplY3RzIGFuZCB0aGVpciBtb2RpZmllcnNcXG5mb3Igb2JqIGluIGJweS5kYXRhLm9iamVjdHM6XFxuICAgIGlmIG9iai50eXBlID09ICdNRVNIJzpcXG4gICAgICAgIG1vZHMgPSBbKG0ubmFtZSwgbS50eXBlKSBmb3IgbSBpbiBvYmoubW9kaWZpZXJzXVxcbiAgICAgICAgbWF0cyA9IFttLm5hbWUgZm9yIG0gaW4gb2JqLmRhdGEubWF0ZXJpYWxzXSBpZiBvYmouZGF0YS5tYXRlcmlhbHMgZWxzZSBbXVxcbiAgICAgICAgcHJpbnQoZlxcXCJ7b2JqLm5hbWV9OiBsb2M9e2xpc3Qob2JqLmxvY2F0aW9uKX0sIHNjYWxlPXtsaXN0KG9iai5zY2FsZSl9LCBtb2RzPXttb2RzfSwgbWF0cz17bWF0c31cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMGZkMGRjODZlNzJlYWUxIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQmFja1dhbGw6IGxvYz1bMC4wLCAyLjUsIDIuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fQmFja1dhbGwnXVxcbkJvb2tDb3ZlcjogbG9jPVstMC42MDAwMDAwMjM4NDE4NTc5LCAtMC42OTk5OTk5ODgwNzkwNzEsIDAuMDE5OTk5OTk5NTUyOTY1MTY0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9Cb29rQ292ZXInXVxcbkNoZWNrZXJlZFNwaGVyZTogbG9jPVswLjE1MDAwMDAwNTk2MDQ2NDQ4LCAtMC41NTAwMDAwMTE5MjA5MjksIDAuMjE5OTk5OTk4ODA3OTA3MV0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX0NoZWNrZXJlZFNwaGVyZSddXFxuRmxvb3I6IGxvYz1bMC4wLCAtMy4wLCAtMC4yMDAwMDAwMDI5ODAyMzIyNF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fRmxvb3InXVxcbkdyZWVuQ2xvdGg6IGxvYz1bMi4wLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjAxOTk5OTk5OTU1Mjk2NTE2NF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTb2xpZGlmeScsICdTT0xJRElGWScpXSwgbWF0cz1bJ01fR3JlZW5WZWx2ZXQuMDAxJ11cXG5HcmVlblBhbmVsOiBsb2M9WzIuNzk5OTk5OTUyMzE2Mjg0LCAxLjc5OTk5OTk1MjMxNjI4NDIsIDIuMjAwMDAwMDQ3NjgzNzE2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9HcmVlblBhbmVsJ11cXG5MZW1vbjE6IGxvYz1bMC42OTk5OTk5ODgwNzkwNzEsIC0wLjU1MDAwMDAxMTkyMDkyOSwgMC4wNzk5OTk5OTgyMTE4NjA2Nl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fTGVtb24nXVxcbk9wZW5Cb29rOiBsb2M9Wy0wLjYwMDAwMDAyMzg0MTg1NzksIC0wLjY5OTk5OTk4ODA3OTA3MSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0Jvb2tQYWdlcyddXFxuT3JhbmdlMTogbG9jPVswLjg1MDAwMDAyMzg0MTg1NzksIC0wLjc1LCAwLjA5MDAwMDAwMzU3NjI3ODY5XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcbk9yYW5nZTI6IGxvYz1bMS4wNDk5OTk5NTIzMTYyODQyLCAtMC42NDk5OTk5NzYxNTgxNDIxLCAwLjA3NTAwMDAwMjk4MDIzMjI0XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9PcmFuZ2UnXVxcblJlZENsb3RoOiBsb2M9Wy0yLjIwMDAwMDA0NzY4MzcxNiwgLTEuNSwgMC4wMTk5OTk5OTk1NTI5NjUxNjRdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1JlZFZlbHZldCcsICdNX1JlZFZlbHZldC4wMDEnXVxcblJlZFBhbmVsOiBsb2M9Wy0yLjc5OTk5OTk1MjMxNjI4NCwgMS43OTk5OTk5NTIzMTYyODQyLCAyLjIwMDAwMDA0NzY4MzcxNl0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bXSwgbWF0cz1bJ01fUmVkUGFuZWwnXVxcblN0YW5mb3JkQnVubnk6IGxvYz1bLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl0sIHNjYWxlPVsxLjI5OTk5OTk1MjMxNjI4NDIsIDEuMjk5OTk5OTUyMzE2Mjg0MiwgMS4yOTk5OTk5NTIzMTYyODQyXSwgbW9kcz1bKCdSZW1lc2gnLCAnUkVNRVNIJyksICgnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9CdW5ueUJyb256ZSddXFxuU3V6YW5uZTogbG9jPVsxLjAsIC0wLjA1MDAwMDAwMDc0NTA1ODA2LCAwLjE4MDAwMDAwNzE1MjU1NzM3XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9TdXphbm5lTWFyYmxlJ11cXG5TdXphbm5lQmFzZTogbG9jPVswLjAsIDAuMCwgLTAuMTUwMDAwMDA1OTYwNDY0NDhdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX0J1c3RCYXNlJ11cXG5UYWJsZUVkZ2U6IGxvYz1bMC4wLCAtMS43NSwgLTAuMDUwMDAwMDAwNzQ1MDU4MDZdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9W10sIG1hdHM9WydNX1RhYmxlVG9wJ11cXG5UYWJsZVRvcDogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVtdLCBtYXRzPVsnTV9UYWJsZVRvcCddXFxuVGVhcG90Qm9keTogbG9jPVswLjAsIDAuMCwgMC4wXSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1N1YnN1cmYnLCAnU1VCU1VSRicpXSwgbWF0cz1bJ01fVGVhcG90Q2VyYW1pYyddXFxuVGVhcG90SGFuZGxlOiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5UZWFwb3RMaWQ6IGxvYz1bMC4wLCAwLjAsIDAuMF0sIHNjYWxlPVsxLjAsIDEuMCwgMS4wXSwgbW9kcz1bKCdTdWJzdXJmJywgJ1NVQlNVUkYnKV0sIG1hdHM9WydNX1RlYXBvdENlcmFtaWMnXVxcblRlYXBvdFNwb3V0OiBsb2M9WzAuMCwgMC4wLCAwLjBdLCBzY2FsZT1bMS4wLCAxLjAsIDEuMF0sIG1vZHM9WygnU3Vic3VyZicsICdTVUJTVVJGJyldLCBtYXRzPVsnTV9UZWFwb3RDZXJhbWljJ11cXG5XaGl0ZUNsb3RoOiBsb2M9WzAuMCwgLTAuMjAwMDAwMDAyOTgwMjMyMjQsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XSwgc2NhbGU9WzEuMCwgMS4wLCAxLjBdLCBtb2RzPVsoJ1NvbGlkaWZ5JywgJ1NPTElESUZZJyldLCBtYXRzPVsnTV9XaGl0ZUxpbmVuJ11cXG5XaW5lR2xhc3M6IGxvYz1bMS41NDk5OTk5NTIzMTYyODQyLCAwLjMwMDAwMDAxMTkyMDkyODk2LCAwLjBdLCBzY2FsZT1bMS4xMDAwMDAwMjM4NDE4NTgsIDEuMTAwMDAwMDIzODQxODU4LCAxLjEwMDAwMDAyMzg0MTg1OF0sIG1vZHM9WygnU29saWRpZnknLCAnU09MSURJRlknKV0sIG1hdHM9WydNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBzZWUgc29tZSBtYXRlcmlhbCBkdXBsaWNhdGlvbiBpc3N1ZXMuIExldCBtZSBjbGVhbiB0aG9zZSB1cCBhbmQgbWFrZSByZWZpbmVtZW50cyB0byBpbXByb3ZlIHRoZSBzY2VuZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBGaXggbWF0ZXJpYWwgYXNzaWdubWVudHMgLSBjbGVhbiB1cCBkdXBsaWNhdGVzXFxuIyBSZWRDbG90aCBoYXMgYm90aCBNX1JlZFZlbHZldCBhbmQgTV9SZWRWZWx2ZXQuMDAxXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5jbGVhcigpXFxucmVkX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmFwcGVuZChicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkVmVsdmV0XFxcIl0pXFxuXFxuIyBHcmVlbkNsb3RoIGhhcyBNX0dyZWVuVmVsdmV0LjAwMSBpbnN0ZWFkIG9mIE1fR3JlZW5WZWx2ZXRcXG5ncmVlbl9jbG90aCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuQ2xvdGhcXFwiXVxcbmdyZWVuX2Nsb3RoLmRhdGEubWF0ZXJpYWxzLmNsZWFyKClcXG5ncmVlbl9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX0dyZWVuVmVsdmV0XFxcIl0pXFxuXFxuIyBSZW1vdmUgZHVwbGljYXRlIG1hdGVyaWFsc1xcbmZvciBtYXRfbmFtZSBpbiBbXFxcIk1fUmVkVmVsdmV0LjAwMVxcXCIsIFxcXCJNX0dyZWVuVmVsdmV0LjAwMVxcXCJdOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KG1hdF9uYW1lKVxcbiAgICBpZiBtYXQ6XFxuICAgICAgICBicHkuZGF0YS5tYXRlcmlhbHMucmVtb3ZlKG1hdClcXG5cXG4jIFZlcmlmeVxcbmZvciBuYW1lIGluIFtcXFwiUmVkQ2xvdGhcXFwiLCBcXFwiR3JlZW5DbG90aFxcXCJdOlxcbiAgICBvYmogPSBicHkuZGF0YS5vYmplY3RzW25hbWVdXFxuICAgIHByaW50KGZcXFwie25hbWV9OiB7W20ubmFtZSBmb3IgbSBpbiBvYmouZGF0YS5tYXRlcmlhbHNdfVxcXCIpXFxuXFxucHJpbnQoZlxcXCJcXFxcbkFsbCBtYXRlcmlhbHM6IHtbbS5uYW1lIGZvciBtIGluIGJweS5kYXRhLm1hdGVyaWFsc119XFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTc1Y2YwOTJlYzNkNTkxOSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlJlZENsb3RoOiBbJ01fUmVkVmVsdmV0J11cXG5HcmVlbkNsb3RoOiBbJ01fR3JlZW5WZWx2ZXQnXVxcblxcbkFsbCBtYXRlcmlhbHM6IFsnTV9CYWNrV2FsbCcsICdNX0Jvb2tDb3ZlcicsICdNX0Jvb2tQYWdlcycsICdNX0J1bm55QnJvbnplJywgJ01fQnVzdEJhc2UnLCAnTV9DaGVja2VyZWRTcGhlcmUnLCAnTV9GbG9vcicsICdNX0dyZWVuUGFuZWwnLCAnTV9HcmVlblZlbHZldCcsICdNX0xlbW9uJywgJ01fT3JhbmdlJywgJ01fUmVkUGFuZWwnLCAnTV9SZWRWZWx2ZXQnLCAnTV9TdXphbm5lTWFyYmxlJywgJ01fVGFibGVUb3AnLCAnTV9UZWFwb3RDZXJhbWljJywgJ01fV2hpdGVMaW5lbicsICdNX1dpbmVHbGFzcyddXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiR29vZC4gTm93IGxldCBtZSBjaGVjayB0aGUgU3V6YW5uZSBidXN0IC0gdGhlIGJhc2UgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCBwcm9wZXJseSB1bmRlciBTdXphbm5lLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbiMgRml4IFN1emFubmUgYmFzZSBwb3NpdGlvbmluZ1xcbiMgU3V6YW5uZSBpcyBhdCAoMS4wLCAtMC4wNSwgMC4xOCksIHNoZSdzIHNpemU9MC41IG1vbmtleVxcbiMgVGhlIGJhc2Ugc2hvdWxkIGJlIHVuZGVyIGhlciwgb24gdGhlIHRhYmxlXFxuXFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuXFxuIyBTdXphbm5lJ3MgbW9ua2V5IGhlYWQgYm90dG9tIGlzIGFyb3VuZCB6PTAuMCBpbiBsb2NhbCBzcGFjZSAoc2luY2Ugc2l6ZT0wLjUpXFxuIyBTaGUncyBhdCB6PTAuMTgsIHNvIGhlciBib3R0b20gaXMgYXQgYWJvdXQgej0wLjE4IC0gMC4xID0gMC4wOFxcbiMgUGxhY2UgYmFzZSByaWdodCB1bmRlciBoZXJcXG5iYXNlLmxvY2F0aW9uID0gKHN1emFubmUubG9jYXRpb24ueCwgc3V6YW5uZS5sb2NhdGlvbi55LCAwLjAzKVxcbmJhc2Uuc2NhbGUgPSAoMS4wLCAxLjAsIDEuMClcXG5cXG4jIE1ha2Ugc3VyZSBTdXphbm5lIGlzIHJlc3Rpbmcgb24gdGhlIGJhc2VcXG5zdXphbm5lLmxvY2F0aW9uLnogPSAwLjE4XFxuXFxuIyBBcHBseSBTdXphbm5lJ3Mgcm90YXRpb24gdG8gdGhlIGJhc2UgdG9vXFxuYmFzZS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCAwKVxcblxcbnByaW50KGZcXFwiU3V6YW5uZToge2xpc3Qoc3V6YW5uZS5sb2NhdGlvbil9XFxcIilcXG5wcmludChmXFxcIkJhc2U6IHtsaXN0KGJhc2UubG9jYXRpb24pfVxcXCIpXFxuXFxuIyBOb3cgbGV0IG1lIGFsc28gY2hlY2sgdGhlIGJ1bm55IC0gbWFrZSBzdXJlIGl0IHNpdHMgb24gdGhlIHRhYmxlXFxuYnVubnkgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdGFuZm9yZEJ1bm55XFxcIl1cXG4jIFRoZSBidW5ueSdzIGxvd2VzdCBwb2ludCBzaG91bGQgYmUgYXQgej0wICh0YWJsZSBzdXJmYWNlKVxcbiMgV2l0aCBzY2FsZSAxLjMsIHRoZSBib2R5IHBhcnRzIGdvIGZyb20gej0wIHRvIGFib3V0IHo9MC42KjEuMz0wLjc4XFxuIyBMZXQncyBjaGVjayBpdHMgYm91bmRpbmcgYm94XFxuYnVubnkuZXZhbHVhdGVkX2dldChicHkuY29udGV4dC5ldmFsdWF0ZWRfZGVwc2dyYXBoX2dldCgpKVxcbiMgVGhlIGJ1bm55IHdhcyBidWlsdCB3aXRoIHBhcnRzIGF0IHo9MCB0byB+MC42LCB0aGVuIHNjYWxlZCAxLjNcXG4jIExvd2VzdCBwYXJ0cyBhcmUgdGhlIHBhd3MgYXQgej0wLCBzbyBpdCBzaG91bGQgc2l0IG9uIHRhYmxlXFxuYnVubnkubG9jYXRpb24ueiA9IDAuMDMgICMgc2xpZ2h0IGxpZnQgZm9yIGNsb3RoIHRoaWNrbmVzc1xcblxcbiMgQWRqdXN0IGJ1bm55IHJvdGF0aW9uIHNvIGl0IGZhY2VzIHNsaWdodGx5IHRvd2FyZCBjYW1lcmFcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCAwLCBtYXRoLnJhZGlhbnMoNDApKVxcblxcbnByaW50KGZcXFwiQnVubnk6IHtsaXN0KGJ1bm55LmxvY2F0aW9uKX1cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hMjUwMTAxYTgwYzZiMWIzIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMTgwMDAwMDA3MTUyNTU3MzddXFxuQmFzZTogWzEuMCwgLTAuMDUwMDAwMDAwNzQ1MDU4MDYsIDAuMDI5OTk5OTk5MzI5NDQ3NzQ2XVxcbkJ1bm55OiBbLTEuMTQ5OTk5OTc2MTU4MTQyLCAwLjI1LCAwLjAyOTk5OTk5OTMyOTQ0Nzc0Nl1cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIGRvIGEgcHJvcGVyIHJlbmRlciB0byBldmFsdWF0ZSB0aGUgZnVsbCBjb21wb3NpdGlvbi4gSSdsbCByZWR1Y2Ugc2FtcGxlcyB0ZW1wb3JhcmlseSBmb3IgZmFzdGVyIGZlZWRiYWNrLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNjFmMDI1ZTY0MDY4NzMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRlbXBvcmFyaWx5IHJlZHVjZSBzYW1wbGVzIGZvciBmYXN0ZXIgcHJldmlld1xcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUuY3ljbGVzLnVzZV9kZW5vaXNpbmcgPSBUcnVlXFxuXFxuIyBTZXQgcmVuZGVyIG91dHB1dFxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiXFxuXFxuIyBSZW5kZXJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5wcmludChcXFwiUHJldmlldyByZW5kZXIgY29tcGxldGUuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjYxZjAyNWU2NDA2ODczMSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlByZXZpZXcgcmVuZGVyIGNvbXBsZXRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTgzODAyODM2NzE2MjMxMWMiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Mi5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBEZXRhaWxlZCBncmlkIGFuYWx5c2lzXFxucHJpbnQoZlxcXCJJbWFnZToge3d9eHtofVxcXCIpXFxucHJpbnQoXFxcIlxcXFxuQnJpZ2h0bmVzcyBtYXAgKDR4NiBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg2KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDYpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gNlxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDZcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDZcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA2XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDE1KTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDE1KTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgICMgQ3JlYXRlIEFTQ0lJIGJyaWdodG5lc3MgbWFwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjE6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKYgCBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODM4MDI4MzY3MTYyMzExYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoNHg2IGdyaWQpOlxcbiAgUm93IDA6IHzigKIgwrcg4oCiIOKAoiAgICAgfFxcbiAgUm93IDE6IHzil4sg4paTIOKWkiDimIAgwrcgICB8XFxuICBSb3cgMjogfOKWkiDilogg4piAIOKXiyDil4sgwrcgfFxcbiAgUm93IDM6IHzil4sg4piAIOKWkiDimIAg4piAIOKYgCB8XFxuICBSb3cgNDogfCAg4peLIOKWkyDigKIg4paSIOKWkyB8XFxuICBSb3cgNTogfCAg4piAIOKWkyDigKIg4paSIOKWkyB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiSSBjYW4gc2VlIHRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgLSBicmlnaHQgb2JqZWN0cyBpbiB0aGUgY2VudGVyIGFuZCBsb3dlci1sZWZ0LCB3aXRoIHRoZSB0YWJsZSBlZGdlIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIHZpZXcgdGhlIGFjdHVhbCBzY3JlZW5zaG90IG5vdy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODg5MGMwMDdmY2NlODVlYiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBTZXQgdGhlIHJlbmRlciBvdXRwdXQgdG8gc2hvdyBpbiB0aGUgaW1hZ2UgZWRpdG9yXFxuZm9yIGFyZWEgaW4gYnB5LmNvbnRleHQuc2NyZWVuLmFyZWFzOlxcbiAgICBpZiBhcmVhLnR5cGUgPT0gJ0lNQUdFX0VESVRPUic6XFxuICAgICAgICBmb3Igc3BhY2UgaW4gYXJlYS5zcGFjZXM6XFxuICAgICAgICAgICAgaWYgc3BhY2UudHlwZSA9PSAnSU1BR0VfRURJVE9SJzpcXG4gICAgICAgICAgICAgICAgaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXcyLnBuZ1xcXCIpXFxuICAgICAgICAgICAgICAgIHNwYWNlLmltYWdlID0gaW1nXFxuICAgICAgICAgICAgICAgIGJyZWFrXFxuICAgICAgICBicmVha1xcblxcbiMgQWxzbyB0cnkgdG8gdmlldyBpdCBpbiB0aGUgM0Qgdmlld3BvcnQgYXMgYmFja2dyb3VuZFxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODkwYzAwN2ZjY2U4NWViIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH1cbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYTMxYWVjZmRlZjI3YzA3YSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWEzMWFlY2ZkZWYyN2MwN2EiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSBtYWtlIHNpZ25pZmljYW50IGltcHJvdmVtZW50cyB0byB0aGUgc2NlbmUuIEknbGwgcmVmaW5lIHRoZSBsaWdodGluZyBmb3IgYmV0dGVyIGNoaWFyb3NjdXJvLCBpbXByb3ZlIHRoZSB0ZWFwb3QgbWF0ZXJpYWwsIGFuZCBhZGp1c3QgdGhlIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNmIyZmUzZTg5NDAyY2RhIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVGSU5FTUVOVFM6IEJldHRlciBsaWdodGluZywgY29tcG9zaXRpb24sIGFuZCBtYXRlcmlhbHNcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgLS0tIDEuIEltcHJvdmUgbGlnaHRpbmcgZm9yIHN0cm9uZ2VyIGNoaWFyb3NjdXJvIC0tLVxcbiMgUmVtb3ZlIGV4aXN0aW5nIGxpZ2h0c1xcbmZvciBvYmogaW4gbGlzdChicHkuZGF0YS5vYmplY3RzKTpcXG4gICAgaWYgb2JqLnR5cGUgPT0gJ0xJR0hUJzpcXG4gICAgICAgIGJweS5kYXRhLm9iamVjdHMucmVtb3ZlKG9iaiwgZG9fdW5saW5rPVRydWUpXFxuXFxuIyBLZXkgbGlnaHQ6IHdhcm0gd2luZG93IHNoYWZ0IGZyb20gdXBwZXItbGVmdCwgbW9yZSBkcmFtYXRpY1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KC0yLjUsIC0wLjUsIDMuNSkpXFxua2V5X2xpZ2h0ID0gYnB5LmNvbnRleHQuYWN0aXZlX29iamVjdFxcbmtleV9saWdodC5uYW1lID0gXFxcIktleUxpZ2h0X1dhcm1TaGFmdFxcXCJcXG5rZXlfbGlnaHQuZGF0YS5lbmVyZ3kgPSAxMjAwXFxua2V5X2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjgyLCAwLjU1KSAgIyB3YXJtIGNhbmRsZS93aW5kb3cgbGlnaHRcXG5rZXlfbGlnaHQuZGF0YS5zaXplID0gMS41XFxua2V5X2xpZ2h0LmRhdGEuc2l6ZV95ID0gMi41XFxua2V5X2xpZ2h0LnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg1NSksIG1hdGgucmFkaWFucygtMTUpLCBtYXRoLnJhZGlhbnMoMjUpKVxcblxcbiMgVmVyeSBzdWJ0bGUgZmlsbCBmcm9tIHJpZ2h0IHRvIHByZXZlbnQgdG90YWwgYmxhY2tuZXNzXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J0FSRUEnLCBsb2NhdGlvbj0oMy41LCAxLjAsIDIuMCkpXFxuZmlsbF9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5maWxsX2xpZ2h0Lm5hbWUgPSBcXFwiRmlsbExpZ2h0X0RpbVxcXCJcXG5maWxsX2xpZ2h0LmRhdGEuZW5lcmd5ID0gMTVcXG5maWxsX2xpZ2h0LmRhdGEuY29sb3IgPSAoMC41LCAwLjYsIDAuOClcXG5maWxsX2xpZ2h0LmRhdGEuc2l6ZSA9IDQuMFxcbmZpbGxfbGlnaHQucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDcwKSwgbWF0aC5yYWRpYW5zKDE1KSwgbWF0aC5yYWRpYW5zKC00MCkpXFxuXFxuIyBTdWJ0bGUgd2FybSByaW0gZnJvbSBiZWhpbmQtcmlnaHQgdG8gc2VwYXJhdGUgb2JqZWN0c1xcbmJweS5vcHMub2JqZWN0LmxpZ2h0X2FkZCh0eXBlPSdBUkVBJywgbG9jYXRpb249KDEuNSwgMi41LCAyLjApKVxcbnJpbV9saWdodCA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5yaW1fbGlnaHQubmFtZSA9IFxcXCJSaW1MaWdodF9XYXJtXFxcIlxcbnJpbV9saWdodC5kYXRhLmVuZXJneSA9IDQwXFxucmltX2xpZ2h0LmRhdGEuY29sb3IgPSAoMS4wLCAwLjc1LCAwLjQpXFxucmltX2xpZ2h0LmRhdGEuc2l6ZSA9IDIuMFxcbnJpbV9saWdodC5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTAwKSwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxuXFxuIyAtLS0gMi4gQWRkIGEgd2luZG93IGZyYW1lIHRvIGNyZWF0ZSBsaWdodCBzaGFmdCBwYXR0ZXJuIC0tLVxcbiMgV2luZG93IGZyYW1lIChkYXJrIHdvb2QsIHBhcnRpYWxseSB2aXNpYmxlIG9uIGxlZnQpXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV9jdWJlX2FkZChzaXplPTEsIGxvY2F0aW9uPSgtMy4yLCAtMC41LCAyLjUpKVxcbndpbmRvd19mcmFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG53aW5kb3dfZnJhbWUubmFtZSA9IFxcXCJXaW5kb3dGcmFtZVxcXCJcXG53aW5kb3dfZnJhbWUuc2NhbGUgPSAoMC4xLCAyLjAsIDMuMClcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPUZhbHNlLCBzY2FsZT1UcnVlKVxcblxcbiMgQXNzaWduIGRhcmsgd29vZCBtYXRlcmlhbFxcbndpbmRvd19mcmFtZS5kYXRhLm1hdGVyaWFscy5hcHBlbmQoYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1RhYmxlVG9wXFxcIl0pXFxuXFxuIyAtLS0gMy4gQWRqdXN0IGNhbWVyYSBmb3IgYmV0dGVyIGNvbXBvc2l0aW9uIC0tLVxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjUsIC00LjAsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKC0wLjEsIDAuMCwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJMaWdodGluZyBhbmQgY2FtZXJhIHJlZmluZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImxpZ2h0c1xcXCI6IFtvLm5hbWUgZm9yIG8gaW4gYnB5LmRhdGEub2JqZWN0cyBpZiBvLnR5cGUgPT0gJ0xJR0hUJ119XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTZiMmZlM2U4OTQwMmNkYSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwibGlnaHRzXCI6IFtcbiAgICAgIFwiRmlsbExpZ2h0X0RpbVwiLFxuICAgICAgXCJLZXlMaWdodF9XYXJtU2hhZnRcIixcbiAgICAgIFwiUmltTGlnaHRfV2FybVwiXG4gICAgXVxuICB9LFxuICBcInN0ZG91dFwiOiBcIkxpZ2h0aW5nIGFuZCBjYW1lcmEgcmVmaW5lZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MzhlNjA4ZWQyNzcxOTU1IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFJlbmRlciBwcmV2aWV3IHdpdGggaW1wcm92ZWQgbGlnaHRpbmdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLmN5Y2xlcy51c2VfZGVub2lzaW5nID0gVHJ1ZVxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3My5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplIHRoZSByZXN1bHRcXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzMucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KGZcXFwiSW1hZ2U6IHt3fXh7aH1cXFwiKVxcbnByaW50KFxcXCJcXFxcbkJyaWdodG5lc3MgbWFwICg4eDggZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoOCk6XFxuICAgIHJvdyA9IFxcXCJcXFwiXFxuICAgIGZvciBneCBpbiByYW5nZSg4KTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDhcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyA4XFxuICAgICAgICB5MSA9IGd5ICogaCAvLyA4XFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gOFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyMCk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyMCk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA4OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjE1OiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yNTogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM1OiByb3cgKz0gXFxcIuKXiyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNDU6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41NTogcm93ICs9IFxcXCLilpMgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjc6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTM4ZTYwOGVkMjc3MTk1NSIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkltYWdlOiAxNTM2eDE1MzZcXG5cXG5CcmlnaHRuZXNzIG1hcCAoOHg4IGdyaWQpOlxcbiAgUm93IDA6IHzCtyDCtyAgICAgwrcg4oCiIOKAoiDCtyB8XFxuICBSb3cgMTogfMK3IMK3IOKAoiDil4sg4peLICAgICAgIHxcXG4gIFJvdyAyOiB84peLIOKWkyDilpIg4paSIOKWkyDigKIgICAgIHxcXG4gIFJvdyAzOiB84paSIOKWiCDilogg4peLIOKXiyDil48g4peLIMK3IHxcXG4gIFJvdyA0OiB84pePIOKXjyDilpMg4paIIOKWkyDil48g4pePIOKXjyB8XFxuICBSb3cgNTogfMK3ICAg4oCiIOKWkyDil4sg4paSIOKWkiDilpMgfFxcbiAgUm93IDY6IHzilogg4oCiIOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilogg4oCiIOKWkyDilpIgwrcg4paSIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTg0MjE3ODdlNjQ3NWNjYWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04NDIxNzg3ZTY0NzVjY2FkIiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJUaGUgYnJpZ2h0bmVzcyBtYXAgc2hvd3MgdGhlIG9iamVjdHMgYXJlIGNvbmNlbnRyYXRlZCBpbiB0aGUgY2VudGVyIHdpdGggdGhlIHdhcm0gbGlnaHQgZnJvbSB0aGUgbGVmdC4gSSBjYW4gc2VlIHRoZSB0YWJsZSBlZGdlIGF0IHRoZSBib3R0b20gYW5kIHRoZSBjb21wb3NpdGlvbiBpcyBmb3JtaW5nLiBMZXQgbWUgbm93IG1ha2Ugc2lnbmlmaWNhbnQgcmVmaW5lbWVudHM6IGltcHJvdmUgdGhlIHRlYXBvdCBtYXRlcmlhbCB0byBiZSBtb3JlIHNpbHZlci9jZXJhbWljLCBmaXggdGhlIHdpbmUgZ2xhc3MgdG8gY29udGFpbiB3aW5lLCBhbmQgZW5oYW5jZSB0aGUgY2xvdGggZHJhcGluZy4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBURUFQT1QgTUFURVJJQUw6IFNpbHZlci9WZXJtZWVyIGNlcmFtaWMgd2l0aCBhZ2VkIHBhdGluYVxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxubWF0LCBudCA9IGNyZWF0ZV9tYXRlcmlhbChcXFwiTV9UZWFwb3RTaWx2ZXJcXFwiKVxcblxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDgwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDQwMCwgMCkpXFxuXFxuIyBTaWx2ZXItaXNoIGJhc2Ugd2l0aCB3YXJtIGNlcmFtaWMgdW5kZXJ0b25lc1xcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjgyLCAwLjc4LCAwLjcyLCAxLjApXFxuYnNkZi5pbnB1dHNbJ01ldGFsbGljJ10uZGVmYXVsdF92YWx1ZSA9IDAuN1xcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4yMlxcbmJzZGYuaW5wdXRzWydTcGVjdWxhciBJT1IgTGV2ZWwnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxuXFxuIyBDb2xvciB2YXJpYXRpb246IHNpbHZlciB0byB3YXJtZXIgYnJvbnplIGFyZWFzXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNi4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDIwMCkpXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNzIsIDAuNjYsIDAuNTUsIDEuMCkgICMgd2FybWVyIGJyb256ZVxcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjg1LCAwLjgyLCAwLjc2LCAxLjApICAjIHNpbHZlclxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBNZXRhbGxpYyB2YXJpYXRpb25cXG5jb2xvcl9yYW1wMiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDAsIDApKVxcbm50LmxpbmtzLm5ldyhub2lzZS5vdXRwdXRzWydGYWMnXSwgY29sb3JfcmFtcDIuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wMi5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuNSwgMC41LCAwLjUsIDEuMCkgICMgbGVzcyBtZXRhbGxpYyAoYnJvbnplKVxcbmNvbG9yX3JhbXAyLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC44NSwgMC44NSwgMC44NSwgMS4wKSAgIyBtb3JlIG1ldGFsbGljIChzaWx2ZXIpXFxubnQubGlua3MubmV3KGNvbG9yX3JhbXAyLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydNZXRhbGxpYyddKVxcblxcbiMgU3VidGxlIHN1cmZhY2UgYnVtcCBmb3IgYWdlZCBmZWVsXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMjAwLCAtMTUwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxubm9pc2UzID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTIwMCwgLTE1MCkpXFxubm9pc2UzLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNjAuMFxcbm5vaXNlMy5pbnB1dHNbJ0RldGFpbCddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobm9pc2UzLm91dHB1dHNbJ0ZhYyddLCBidW1wLmlucHV0c1snSGVpZ2h0J10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG4jIEFzc2lnbiB0byBhbGwgdGVhcG90IHBhcnRzXFxuZm9yIG5hbWUgaW4gW1xcXCJUZWFwb3RCb2R5XFxcIiwgXFxcIlRlYXBvdFNwb3V0XFxcIiwgXFxcIlRlYXBvdEhhbmRsZVxcXCIsIFxcXCJUZWFwb3RMaWRcXFwiXTpcXG4gICAgb2JqID0gYnB5LmRhdGEub2JqZWN0c1tuYW1lXVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuY2xlYXIoKVxcbiAgICBvYmouZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIFJlbW92ZSBvbGQgbWF0ZXJpYWxcXG5vbGQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1RlYXBvdENlcmFtaWNcXFwiKVxcbmlmIG9sZDpcXG4gICAgYnB5LmRhdGEubWF0ZXJpYWxzLnJlbW92ZShvbGQpXFxuXFxucHJpbnQoXFxcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYmY4MTU4NTYwZmQ0ODBmNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIlRlYXBvdCBzaWx2ZXIgbWF0ZXJpYWwgaW1wcm92ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWUzZTRhYzgxNzExOGUxOCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG5kZWYgY3JlYXRlX21hdGVyaWFsKG5hbWUpOlxcbiAgICBtYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMubmV3KG5hbWUpXFxuICAgIG1hdC51c2Vfbm9kZXMgPSBUcnVlXFxuICAgIG50ID0gbWF0Lm5vZGVfdHJlZVxcbiAgICBmb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgICAgIG50Lm5vZGVzLnJlbW92ZShuKVxcbiAgICByZXR1cm4gbWF0LCBudFxcblxcbmRlZiBhZGRfbm9kZShudCwgbm9kZV90eXBlLCBsb2NhdGlvbj0oMCwwKSk6XFxuICAgIG4gPSBudC5ub2Rlcy5uZXcobm9kZV90eXBlKVxcbiAgICBuLmxvY2F0aW9uID0gbG9jYXRpb25cXG4gICAgcmV0dXJuIG5cXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBXSU5FIEdMQVNTOiBBZGQgcmVkIHdpbmUgaW5zaWRlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIENyZWF0ZSBhIHNlcGFyYXRlIHdpbmUgbGlxdWlkIG1lc2ggaW5zaWRlIHRoZSBnbGFzc1xcbmltcG9ydCBibWVzaFxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaW5lTGlxdWlkTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgUHJvZmlsZSBvZiB3aW5lIHN1cmZhY2UgKGEgbGF0aGVkIGJvd2wgc2hhcGUsIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBnbGFzcylcXG53aW5lX3Byb2ZpbGUgPSBbXFxuICAgICgwLjAwLCAwLjMwKSwgICAgIyBjZW50ZXIgYm90dG9tXFxuICAgICgwLjA2LCAwLjMwKSwgICAgIyBcXG4gICAgKDAuMDgsIDAuMzEpLCAgICAjIFxcbiAgICAoMC4xMCwgMC4zMiksICAgICMgXFxuICAgICgwLjExLCAwLjM0KSwgICAgIyBib3dsXFxuICAgICgwLjEyLCAwLjM2KSwgICAgIyBcXG4gICAgKDAuMTI1LCAwLjM4KSwgICAjIFxcbiAgICAoMC4xMiwgMC40MCksICAgICMgXFxuICAgICgwLjExLCAwLjQyKSwgICAgIyBcXG4gICAgKDAuMTAsIDAuNDQpLCAgICAjIHdpbmUgc3VyZmFjZSBsZXZlbFxcbiAgICAoMC4wMCwgMC40NCksICAgICMgY2VudGVyIHRvcCAod2luZSBzdXJmYWNlKVxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiB3aW5lX3Byb2ZpbGU6XFxuICAgIHJpbmcgPSBbXVxcbiAgICBpZiByIDwgMC4wMDE6XFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCgwLCAwLCBoKSlcXG4gICAgICAgIHJpbmcgPSBbdl0gKiBzZWdtZW50c1xcbiAgICBlbHNlOlxcbiAgICAgICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgICAgIGFuZ2xlID0gKGkgLyBzZWdtZW50cykgKiBtYXRoLnRhdVxcbiAgICAgICAgICAgIHggPSByICogbWF0aC5jb3MoYW5nbGUpXFxuICAgICAgICAgICAgeSA9IHIgKiBtYXRoLnNpbihhbmdsZSlcXG4gICAgICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCBoKSlcXG4gICAgICAgICAgICByaW5nLmFwcGVuZCh2KVxcbiAgICBhbGxfdmVydHMuYXBwZW5kKHJpbmcpXFxuXFxuYm0udmVydHMuZW5zdXJlX2xvb2t1cF90YWJsZSgpXFxuXFxuZm9yIHJpIGluIHJhbmdlKGxlbihhbGxfdmVydHMpIC0gMSk6XFxuICAgIHJpbmdfYSA9IGFsbF92ZXJ0c1tyaV1cXG4gICAgcmluZ19iID0gYWxsX3ZlcnRzW3JpICsgMV1cXG4gICAgcmEsIF8gPSB3aW5lX3Byb2ZpbGVbcmldXFxuICAgIHJiLCBfID0gd2luZV9wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgICMgQ2FwIHRoZSB0b3AgKHdpbmUgc3VyZmFjZSlcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Fbal1dKVxcbiAgICAgICAgZWxzZTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal0sIHJpbmdfYVtqXV0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndpbmVfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldpbmVMaXF1aWRcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdpbmVfb2JqKVxcbndpbmVfb2JqLmxvY2F0aW9uID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl0ubG9jYXRpb24uY29weSgpXFxud2luZV9vYmouc2NhbGUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXS5zY2FsZS5jb3B5KClcXG53aW5lX29iai5yb3RhdGlvbl9ldWxlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIldpbmVHbGFzc1xcXCJdLnJvdGF0aW9uX2V1bGVyLmNvcHkoKVxcblxcbiMgV2luZSBtYXRlcmlhbCAtIGRlZXAgcmVkLCBzbGlnaHRseSB0cmFuc2x1Y2VudFxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fUmVkV2luZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNjAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMzAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4zNSwgMC4wMiwgMC4wMywgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC4xXFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5ic2RmLmlucHV0c1snVHJhbnNtaXNzaW9uIFdlaWdodCddLmRlZmF1bHRfdmFsdWUgPSAwLjNcXG5ic2RmLmlucHV0c1snSU9SJ10uZGVmYXVsdF92YWx1ZSA9IDEuMzNcXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG53aW5lX29iai5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbnByaW50KFxcXCJXaW5lIGxpcXVpZCBhZGRlZCB0byBnbGFzcy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hZTNlNGFjODE3MTE4ZTE4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2luZSBsaXF1aWQgYWRkZWQgdG8gZ2xhc3MuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiTm93IGxldCBtZSBpbXByb3ZlIHRoZSBjbG90aCBkcmFwaW5nIGFuZCBhZGQgbW9yZSBmb2xkIHN0cnVjdHVyZS4gTGV0IG1lIGFsc28gZW5oYW5jZSB0aGUgYmFjayB3YWxsIHRvIGZlZWwgbW9yZSBsaWtlIGEgRHV0Y2ggcGFpbnRpbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWJmNWU2MTJhYmEwYTBiNzkiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuaW1wb3J0IHJhbmRvbVxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG5yYW5kb20uc2VlZCg3KVxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENMT1RIIEZPTERTOiBNb3JlIGRyYW1hdGljIGRyYXBpbmdcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgUmVidWlsZCB0aGUgcmVkIGNsb3RoIHdpdGggYmV0dGVyIGRyYXBpbmcgKGhhbmdpbmcgb2ZmIHRhYmxlIGVkZ2UpXFxucmVkX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiUmVkQ2xvdGhcXFwiXVxcbiMgUmVtb3ZlIGFuZCByZWJ1aWxkXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUocmVkX2Nsb3RoLCBkb191bmxpbms9VHJ1ZSlcXG5tYXRfcmVkID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1JlZFZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIlJlZENsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbiMgQ3JlYXRlIGEgY2xvdGggdGhhdCBkcmFwZXMgb3ZlciB0aGUgbGVmdCBlZGdlIG9mIHRoZSB0YWJsZVxcbiMgR3JpZCBvZiB2ZXJ0aWNlc1xcbmNvbHMgPSA1MFxcbnJvd3MgPSA0MFxcbndpZHRoID0gMy41XFxubGVuZ3RoID0gMy41XFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBDcmVhdGUgZm9sZHM6IHRoZSBjbG90aCBoYW5ncyBvZmYgdGhlIGZyb250IGVkZ2UgKHkgPCAtMC41KVxcbiAgICAgICAgIyBhbmQgaGFzIHJpcHBsZSBmb2xkcyBvbiB0aGUgdGFibGUgc3VyZmFjZVxcbiAgICAgICAgaWYgeSA8IC0wLjU6XFxuICAgICAgICAgICAgIyBIYW5naW5nIGRvd24gb3ZlciB0aGUgZWRnZVxcbiAgICAgICAgICAgIGVkZ2VfZGlzdCA9IGFicyh5ICsgMC41KVxcbiAgICAgICAgICAgIHogPSAtZWRnZV9kaXN0ICogMC44XFxuICAgICAgICAgICAgIyBBZGQgdmVydGljYWwgZm9sZHMgaW4gdGhlIGhhbmdpbmcgcGFydFxcbiAgICAgICAgICAgIHogKz0gMC4wNSAqIG1hdGguc2luKHggKiA4KSAqIG1pbigxLjAsIGVkZ2VfZGlzdCAqIDIpXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgICMgT24gdGhlIHRhYmxlOiBnZW50bGUgcmlwcGxlc1xcbiAgICAgICAgICAgIHogPSAwLjAyICogbWF0aC5zaW4oeCAqIDYgKyB5ICogMylcXG4gICAgICAgICAgICB6ICs9IDAuMDE1ICogbWF0aC5jb3MoeSAqIDgpXFxuICAgICAgICBcXG4gICAgICAgICMgQWRkIG5vaXNlIGZvciBuYXR1cmFsIHZhcmlhdGlvblxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMSwgMC4wMSlcXG4gICAgICAgIFxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgeikpXFxuICAgICAgICByb3cuYXBwZW5kKHYpXFxuICAgIHZlcnRzX2dyaWQuYXBwZW5kKHJvdylcXG5cXG4jIENyZWF0ZSBmYWNlc1xcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbnJlZF9jbG90aCA9IGJweS5kYXRhLm9iamVjdHMubmV3KFxcXCJSZWRDbG90aFxcXCIsIG1lc2gpXFxuYnB5LmNvbnRleHQuc2NlbmUuY29sbGVjdGlvbi5vYmplY3RzLmxpbmsocmVkX2Nsb3RoKVxcbnJlZF9jbG90aC5sb2NhdGlvbiA9ICgtMS44LCAtMC4zLCAwLjAxKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSByZWRfY2xvdGhcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbiMgQWRkIHNvbGlkaWZ5XFxubW9kID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlNvbGlkaWZ5XFxcIiwgJ1NPTElESUZZJylcXG5tb2QudGhpY2tuZXNzID0gMC4wMTJcXG5tb2Qub2Zmc2V0ID0gMFxcblxcbiMgQWRkIHN1YnN1cmYgZm9yIHNtb290aG5lc3NcXG5tb2QyID0gcmVkX2Nsb3RoLm1vZGlmaWVycy5uZXcoXFxcIlN1YnN1cmZcXFwiLCAnU1VCU1VSRicpXFxubW9kMi5sZXZlbHMgPSAxXFxubW9kMi5yZW5kZXJfbGV2ZWxzID0gMlxcblxcbnJlZF9jbG90aC5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0X3JlZClcXG5cXG5wcmludChcXFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1iZjVlNjEyYWJhMGEwYjc5IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGNsb3RoIHJlYnVpbHQgd2l0aCBiZXR0ZXIgZHJhcGluZy5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MGU4YjMzMTQ4Mzc0MDcxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgYm1lc2hcXG5pbXBvcnQgbWF0aFxcbmltcG9ydCByYW5kb21cXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxucmFuZG9tLnNlZWQoOClcXG5cXG4jIFJlYnVpbGQgZ3JlZW4gY2xvdGggd2l0aCBiZXR0ZXIgZHJhcGluZ1xcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiR3JlZW5DbG90aFxcXCJdXFxuYnB5LmRhdGEub2JqZWN0cy5yZW1vdmUoZ3JlZW5fY2xvdGgsIGRvX3VubGluaz1UcnVlKVxcbm1hdF9ncmVlbiA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxuXFxubWVzaCA9IGJweS5kYXRhLm1lc2hlcy5uZXcoXFxcIkdyZWVuQ2xvdGhNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuY29scyA9IDQwXFxucm93cyA9IDQwXFxud2lkdGggPSAzLjBcXG5sZW5ndGggPSAzLjBcXG5cXG52ZXJ0c19ncmlkID0gW11cXG5mb3IgcmkgaW4gcmFuZ2Uocm93cyArIDEpOlxcbiAgICByb3cgPSBbXVxcbiAgICBmb3IgY2kgaW4gcmFuZ2UoY29scyArIDEpOlxcbiAgICAgICAgeCA9IChjaSAvIGNvbHMgLSAwLjUpICogd2lkdGhcXG4gICAgICAgIHkgPSAocmkgLyByb3dzIC0gMC41KSAqIGxlbmd0aFxcbiAgICAgICAgeiA9IDAuMFxcbiAgICAgICAgXFxuICAgICAgICAjIEdyZWVuIGNsb3RoIG9uIHJpZ2h0IHNpZGUsIGRyYXBlZCB3aXRoIGZvbGRzXFxuICAgICAgICAjIFRoZSBiYWNrIHBhcnQgcmlzZXMgc2xpZ2h0bHkgKGFnYWluc3QgdGhlIHdhbGwpXFxuICAgICAgICBpZiB5ID4gMC44OlxcbiAgICAgICAgICAgIHogPSAoeSAtIDAuOCkgKiAwLjNcXG4gICAgICAgIGVsc2U6XFxuICAgICAgICAgICAgeiA9IDAuMDIgKiBtYXRoLnNpbih4ICogNSArIHkgKiA0KVxcbiAgICAgICAgICAgIHogKz0gMC4wMTUgKiBtYXRoLmNvcyh5ICogNylcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDgsIDAuMDA4KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbmdyZWVuX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkdyZWVuQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKGdyZWVuX2Nsb3RoKVxcbmdyZWVuX2Nsb3RoLmxvY2F0aW9uID0gKDEuOCwgMC41LCAwLjAxKVxcbmdyZWVuX2Nsb3RoLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtNSkpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IGdyZWVuX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSBncmVlbl9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDEyXFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gZ3JlZW5fY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuZ3JlZW5fY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF9ncmVlbilcXG5cXG5wcmludChcXFwiR3JlZW4gY2xvdGggcmVidWlsdCB3aXRoIGJldHRlciBkcmFwaW5nLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTkwZThiMzMxNDgzNzQwNzEiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJHcmVlbiBjbG90aCByZWJ1aWx0IHdpdGggYmV0dGVyIGRyYXBpbmcuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOTU3YzBkYjU3Y2I3OWE4ZSIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IGJtZXNoXFxuaW1wb3J0IG1hdGhcXG5pbXBvcnQgcmFuZG9tXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbnJhbmRvbS5zZWVkKDkpXFxuXFxuIyBSZWJ1aWxkIHdoaXRlL25ldXRyYWwgbGluZW4gcnVubmVyXFxud2hpdGVfY2xvdGggPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaGl0ZUNsb3RoXFxcIl1cXG5icHkuZGF0YS5vYmplY3RzLnJlbW92ZSh3aGl0ZV9jbG90aCwgZG9fdW5saW5rPVRydWUpXFxubWF0X3doaXRlID0gYnB5LmRhdGEubWF0ZXJpYWxzW1xcXCJNX1doaXRlTGluZW5cXFwiXVxcblxcbm1lc2ggPSBicHkuZGF0YS5tZXNoZXMubmV3KFxcXCJXaGl0ZUNsb3RoTWVzaFxcXCIpXFxuYm0gPSBibWVzaC5uZXcoKVxcblxcbmNvbHMgPSA0MFxcbnJvd3MgPSAzNVxcbndpZHRoID0gMi41XFxubGVuZ3RoID0gMi4yXFxuXFxudmVydHNfZ3JpZCA9IFtdXFxuZm9yIHJpIGluIHJhbmdlKHJvd3MgKyAxKTpcXG4gICAgcm93ID0gW11cXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMgKyAxKTpcXG4gICAgICAgIHggPSAoY2kgLyBjb2xzIC0gMC41KSAqIHdpZHRoXFxuICAgICAgICB5ID0gKHJpIC8gcm93cyAtIDAuNSkgKiBsZW5ndGhcXG4gICAgICAgIHogPSAwLjBcXG4gICAgICAgIFxcbiAgICAgICAgIyBMaW5lbiBydW5uZXIgd2l0aCBzdWJ0bGUgZm9sZHNcXG4gICAgICAgIHogPSAwLjAxNSAqIG1hdGguc2luKHggKiA0ICsgeSAqIDIpXFxuICAgICAgICB6ICs9IDAuMDEgKiBtYXRoLmNvcyh5ICogNilcXG4gICAgICAgICMgU2xpZ2h0IGRyb29wIGF0IGZyb250IGVkZ2VcXG4gICAgICAgIGlmIHkgPCAtMC43OlxcbiAgICAgICAgICAgIHogLT0gKGFicyh5KSAtIDAuNykgKiAwLjNcXG4gICAgICAgIFxcbiAgICAgICAgeiArPSByYW5kb20udW5pZm9ybSgtMC4wMDUsIDAuMDA1KVxcbiAgICAgICAgXFxuICAgICAgICB2ID0gYm0udmVydHMubmV3KCh4LCB5LCB6KSlcXG4gICAgICAgIHJvdy5hcHBlbmQodilcXG4gICAgdmVydHNfZ3JpZC5hcHBlbmQocm93KVxcblxcbmZvciByaSBpbiByYW5nZShyb3dzKTpcXG4gICAgZm9yIGNpIGluIHJhbmdlKGNvbHMpOlxcbiAgICAgICAgdjEgPSB2ZXJ0c19ncmlkW3JpXVtjaV1cXG4gICAgICAgIHYyID0gdmVydHNfZ3JpZFtyaV1bY2krMV1cXG4gICAgICAgIHYzID0gdmVydHNfZ3JpZFtyaSsxXVtjaSsxXVxcbiAgICAgICAgdjQgPSB2ZXJ0c19ncmlkW3JpKzFdW2NpXVxcbiAgICAgICAgYm0uZmFjZXMubmV3KFt2MSwgdjIsIHYzLCB2NF0pXFxuXFxuYm0ubm9ybWFsX3VwZGF0ZSgpXFxuYm0udG9fbWVzaChtZXNoKVxcbmJtLmZyZWUoKVxcblxcbndoaXRlX2Nsb3RoID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIldoaXRlQ2xvdGhcXFwiLCBtZXNoKVxcbmJweS5jb250ZXh0LnNjZW5lLmNvbGxlY3Rpb24ub2JqZWN0cy5saW5rKHdoaXRlX2Nsb3RoKVxcbndoaXRlX2Nsb3RoLmxvY2F0aW9uID0gKDAuMCwgLTAuMSwgMC4wMTUpXFxuYnB5LmNvbnRleHQudmlld19sYXllci5vYmplY3RzLmFjdGl2ZSA9IHdoaXRlX2Nsb3RoXFxuYnB5Lm9wcy5vYmplY3Quc2hhZGVfc21vb3RoKClcXG5cXG5tb2QgPSB3aGl0ZV9jbG90aC5tb2RpZmllcnMubmV3KFxcXCJTb2xpZGlmeVxcXCIsICdTT0xJRElGWScpXFxubW9kLnRoaWNrbmVzcyA9IDAuMDA4XFxubW9kLm9mZnNldCA9IDBcXG5cXG5tb2QyID0gd2hpdGVfY2xvdGgubW9kaWZpZXJzLm5ldyhcXFwiU3Vic3VyZlxcXCIsICdTVUJTVVJGJylcXG5tb2QyLmxldmVscyA9IDFcXG5tb2QyLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxud2hpdGVfY2xvdGguZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdF93aGl0ZSlcXG5cXG5wcmludChcXFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXFwiKVxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NTdjMGRiNTdjYjc5YThlIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiV2hpdGUgbGluZW4gY2xvdGggcmVidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJOb3cgbGV0IG1lIHJlbmRlciBhIHByZXZpZXcgdG8gY2hlY2sgdGhlIGltcHJvdmVkIGNvbXBvc2l0aW9uLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3NC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuIyBBbmFseXplXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc0LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXFwiKVxcbmZvciBneSBpbiByYW5nZSg4KTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDgpOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gOFxcbiAgICAgICAgeDIgPSAoZ3grMSkgKiB3IC8vIDhcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDhcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyA4XFxuICAgICAgICBicmlnaHRfc3VtID0gMFxcbiAgICAgICAgY291bnQgPSAwXFxuICAgICAgICBmb3IgeSBpbiByYW5nZSh5MSwgeTIsIDIwKTpcXG4gICAgICAgICAgICBmb3IgeCBpbiByYW5nZSh4MSwgeDIsIDIwKTpcXG4gICAgICAgICAgICAgICAgaWR4ID0gKHkgKiB3ICsgeCkgKiA0XFxuICAgICAgICAgICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICAgICAgICAgIGJyaWdodF9zdW0gKz0gKHBpeGVsc1tpZHhdICsgcGl4ZWxzW2lkeCsxXSArIHBpeGVsc1tpZHgrMl0pIC8gM1xcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxcbiAgICAgICAgYnJpZ2h0ID0gYnJpZ2h0X3N1bSAvIGNvdW50IGlmIGNvdW50ID4gMCBlbHNlIDBcXG4gICAgICAgIGlmIGJyaWdodCA8IDAuMDg6IHJvdyArPSBcXFwiICBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMTU6IHJvdyArPSBcXFwiwrcgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjI1OiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzU6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40NTogcm93ICs9IFxcXCLil48gXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjU1OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNzogcm93ICs9IFxcXCLilpIgXFxcIlxcbiAgICAgICAgZWxzZTogcm93ICs9IFxcXCLiloggXFxcIlxcbiAgICBwcmludChmXFxcIiAgUm93IHtneX06IHx7cm93fXxcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ZjQwODgyMmU5NTA1ODNmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQnJpZ2h0bmVzcyBtYXAgKDh4OCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgICAgIMK3IOKAoiDigKIgwrcgfFxcbiAgUm93IDE6IHzCtyAgIOKAoiDil4sg4peLIOKAoiAgICAgfFxcbiAgUm93IDI6IHzil4sg4paTIOKWkyDil48g4peLIOKAoiAgIMK3IHxcXG4gIFJvdyAzOiB84paSIOKWkiDilpIg4oCiIOKAoiDil48g4oCiIOKAoiB8XFxuICBSb3cgNDogfOKXjyDilpMg4paTIOKWkiDil48g4pePIOKXjyDil4sgfFxcbiAgUm93IDU6IHzCtyAgIOKAoiDilpMg4oCiIOKWkiDilpIg4paTIHxcXG4gIFJvdyA2OiB84pePIMK3IOKXjyDilpIgwrcg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzilpIgwrcg4paTIOKWkiDCtyDilpIg4paSIOKWkiB8XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODJhYTEwYWE1YTllN2E2OCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTgyYWExMGFhNWE5ZTdhNjgiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IkxldCBtZSByZWZpbmUgdGhlIGNvbXBvc2l0aW9uIGFuZCBwb3NpdGlvbmluZyBvZiBvYmplY3RzLCB0aGVuIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgdG8gYmUgbW9yZSByZWZsZWN0aXZlLiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1iNGZiZmE2MzNiZmQyN2E2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcbmZyb20gbWF0aHV0aWxzIGltcG9ydCBWZWN0b3JcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgUkVQT1NJVElPTiBPQkpFQ1RTIEZPUiBCRVRURVIgQ09NUE9TSVRJT05cXG4jIFRlYXBvdCBpcyBoZXJvIChjZW50ZXIpLCBvdmVybGFwcGluZyBkZXB0aCBhcnJhbmdlbWVudFxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuXFxuIyBUZWFwb3QgLSBoZXJvLCBjZW50ZXIsIGNvbW1hbmRpbmdcXG50ZWFwb3QgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJVdGFoVGVhcG90XFxcIl1cXG50ZWFwb3QubG9jYXRpb24gPSAoMC4xLCAwLjAsIDAuMClcXG50ZWFwb3Qucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKC0yMCkpXFxudGVhcG90LnNjYWxlID0gKDAuOSwgMC45LCAwLjkpXFxuXFxuIyBTdGFuZm9yZCBCdW5ueSAtIGxlZnQgb2YgdGVhcG90LCBzbGlnaHRseSBiZWhpbmRcXG5idW5ueSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN0YW5mb3JkQnVubnlcXFwiXVxcbmJ1bm55LmxvY2F0aW9uID0gKC0xLjEsIDAuMywgMC4wMylcXG5idW5ueS5yb3RhdGlvbl9ldWxlciA9ICgwLCBtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoMzUpKVxcbmJ1bm55LnNjYWxlID0gKDEuMiwgMS4yLCAxLjIpXFxuXFxuIyBTdXphbm5lIC0gcmlnaHQgc2lkZSwgYXMgYnVzdCBwb3J0cmFpdCBnYXppbmcgb3V0XFxuc3V6YW5uZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlN1emFubmVcXFwiXVxcbnN1emFubmUubG9jYXRpb24gPSAoMS4xLCAtMC4xLCAwLjIpXFxuc3V6YW5uZS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTApLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzUpKVxcblxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIENoZWNrZXJlZCBzcGhlcmUgLSBmcm9udC1jZW50ZXIsIHNsaWdodGx5IHRvIHJpZ2h0IG9mIHRlYXBvdFxcbnNwaGVyZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNoZWNrZXJlZFNwaGVyZVxcXCJdXFxuc3BoZXJlLmxvY2F0aW9uID0gKDAuMywgLTAuNywgMC4yMilcXG5cXG4jIFdpbmUgZ2xhc3MgLSBmYXIgcmlnaHQsIGJlaGluZCBTdXphbm5lXFxuZ2xhc3MgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJXaW5lR2xhc3NcXFwiXVxcbmdsYXNzLmxvY2F0aW9uID0gKDEuNywgMC41LCAwLjApXFxuZ2xhc3Muc2NhbGUgPSAoMS4xLCAxLjEsIDEuMSlcXG5cXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcbndpbmUuc2NhbGUgPSBnbGFzcy5zY2FsZS5jb3B5KClcXG5cXG4jIE9wZW4gYm9vayAtIGxlZnQtZnJvbnQsIHBhcnRpYWxseSB1bmRlciBidW5ueVxcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC41LCAtMC44LCAwLjAyKVxcbmJvb2sucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5cXG5jb3ZlciA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkJvb2tDb3ZlclxcXCJdXFxuY292ZXIubG9jYXRpb24gPSBib29rLmxvY2F0aW9uLmNvcHkoKVxcbmNvdmVyLnJvdGF0aW9uX2V1bGVyID0gYm9vay5yb3RhdGlvbl9ldWxlci5jb3B5KClcXG5cXG4jIEZydWl0IGNsdXN0ZXIgLSBmcm9udC1yaWdodCwgbmVhciBTdXphbm5lXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiT3JhbmdlMVxcXCJdLmxvY2F0aW9uID0gKDAuOSwgLTAuOCwgMC4wOSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UxXFxcIl0ucm90YXRpb25fZXVsZXIgPSAoMCwgMCwgbWF0aC5yYWRpYW5zKDMwKSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ubG9jYXRpb24gPSAoMS4xLCAtMC43LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJPcmFuZ2UyXFxcIl0ucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDIwKSwgMCwgbWF0aC5yYWRpYW5zKDE1KSlcXG5cXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjc1LCAtMC42NSwgMC4wOClcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5yb3RhdGlvbl9ldWxlciA9IChtYXRoLnJhZGlhbnMoMTUpLCAwLCBtYXRoLnJhZGlhbnMoNTApKVxcblxcbiMgQ2FtZXJhIC0gc2xpZ2h0bHkgZWxldmF0ZWQsIDUwbW0gZXF1aXZhbGVudFxcbmNhbSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbWVyYV9QcmVzZW50YXRpb25cXFwiXVxcbmNhbS5sb2NhdGlvbiA9ICgzLjIsIC00LjIsIDIuMClcXG50YXJnZXQgPSBWZWN0b3IoKDAuMSwgLTAuMSwgMC4zNSkpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbnByaW50KFxcXCJPYmplY3RzIHJlcG9zaXRpb25lZCBmb3IgY29tcG9zaXRpb24uXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYjRmYmZhNjMzYmZkMjdhNiIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIk9iamVjdHMgcmVwb3NpdGlvbmVkIGZvciBjb21wb3NpdGlvbi5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05MWJmNGExYTliNzI5MDFkIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb21wb3NpdGlvblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDI0XFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc1LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtOTFiZjRhMWE5YjcyOTAxZCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8wrcgwrcgwrcgICAgICAgwrcgwrcg4oCiIOKAoiB8XFxuICBSb3cgMTogfOKAoiDCtyAgIMK3IOKAoiDil4sg4peLIOKAoiDigKIg4oCiIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXjyDil48g4pePIOKXiyDil4sgwrcgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkiDilpIg4paTIOKAoiDigKIg4oCiICAgICDigKIgfFxcbiAgUm93IDQ6IHzilogg4paIIOKWiCDilpIgwrcgwrcg4peLIOKAoiDigKIgwrcgfFxcbiAgUm93IDU6IHzilpIg4paIIOKWiCDilogg4paSIOKXiyDil48g4peLIOKAoiDil4sgfFxcbiAgUm93IDY6IHwgIMK3IOKAoiDil48g4paSIOKWkyDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDc6IHzigKIgICDilpMg4paSIOKXiyDil4sg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA4OiB84peLICAg4paSIOKWiCDil4sg4peLIOKWiCDilpIg4paSIOKWkiB8XFxuICBSb3cgOTogfOKXjyAgIOKWkiDilogg4peLIOKXiyDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBjb21wb3NpdGlvbiBpcyBsb29raW5nIGdvb2QgLSBJIGNhbiBzZWUgb2JqZWN0cyBncm91cGVkIGluIHRoZSBjZW50ZXIgd2l0aCB3YXJtIGxpZ2h0IGZyb20gdGhlIGxlZnQgYW5kIHRoZSBncmVlbiBwYW5lbCBvbiB0aGUgcmlnaHQuIFRoZSB0YWJsZSBlZGdlIGlzIHZpc2libGUgYXQgdGhlIGJvdHRvbS4gTGV0IG1lIG5vdyBsb29rIGF0IHRoZSBhY3R1YWwgaW1hZ2UgdG8gYXNzZXNzIGl0IHZpc3VhbGx5LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hM2NmNDQ1MDk5Mjc1ZDQzIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTNjZjQ0NTA5OTI3NWQ0MyIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwNWE5OTI0NGIwYjk5NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBMZXQgbWUgY2hlY2sgdGhlIGltYWdlIG1vcmUgY2FyZWZ1bGx5IGJ5IHNhdmluZyBhIHNtYWxsZXIgdmVyc2lvblxcbiMgYW5kIGV4YW1pbmluZyBjb2xvciBkaXN0cmlidXRpb25cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzUucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgQ29sb3IgYW5hbHlzaXM6IGNoZWNrIGZvciByZWQsIGdyZWVuLCBhbmQgbmV1dHJhbCBhcmVhc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG5uZXV0cmFsX2NvdW50ID0gMFxcbndhcm1fY291bnQgPSAwXFxudG90YWwgPSAwXFxuXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgdG90YWwgKz0gMVxcbiAgICBicmlnaHRuZXNzID0gKHIgKyBnICsgYikgLyAzXFxuICAgIFxcbiAgICBpZiBicmlnaHRuZXNzIDwgMC4wNTpcXG4gICAgICAgIGNvbnRpbnVlXFxuICAgIFxcbiAgICAjIFJlZCBkb21pbmFudFxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgIyBHcmVlbiBkb21pbmFudFxcbiAgICBlbGlmIGcgPiAwLjE1IGFuZCBnID4gciAqIDEuMyBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgICMgV2FybSAoeWVsbG93L29yYW5nZSlcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG4gICAgIyBOZXV0cmFsXFxuICAgIGVsaWYgYWJzKHIgLSBnKSA8IDAuMDUgYW5kIGFicyhnIC0gYikgPCAwLjA1OlxcbiAgICAgICAgbmV1dHJhbF9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJUb3RhbCB2aXNpYmxlIHBpeGVsczoge3RvdGFsfVxcXCIpXFxucHJpbnQoZlxcXCJSZWQgZG9taW5hbnQ6IHtyZWRfY291bnR9ICh7MTAwKnJlZF9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHtncmVlbl9jb3VudH0gKHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5wcmludChmXFxcIldhcm0gKHllbGxvdy9vcmFuZ2UpOiB7d2FybV9jb3VudH0gKHsxMDAqd2FybV9jb3VudC90b3RhbDouMWZ9JSlcXFwiKVxcbnByaW50KGZcXFwiTmV1dHJhbDoge25ldXRyYWxfY291bnR9ICh7MTAwKm5ldXRyYWxfY291bnQvdG90YWw6LjFmfSUpXFxcIilcXG5cXG4jIENoZWNrIGlmIHRlYXBvdCBpcyB2aXNpYmxlIChicmlnaHQgbWV0YWxsaWMgaGlnaGxpZ2h0cylcXG5icmlnaHRfbWV0YWxsaWMgPSAwXFxuZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBpeGVscyksIDQpOlxcbiAgICByLCBnLCBiID0gcGl4ZWxzW2ldLCBwaXhlbHNbaSsxXSwgcGl4ZWxzW2krMl1cXG4gICAgaWYgciA+IDAuNyBhbmQgZyA+IDAuNjUgYW5kIGIgPiAwLjU1OlxcbiAgICAgICAgYnJpZ2h0X21ldGFsbGljICs9IDFcXG5wcmludChmXFxcIlxcXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IHticmlnaHRfbWV0YWxsaWN9ICh7MTAwKmJyaWdodF9tZXRhbGxpYy90b3RhbDouMWZ9JSlcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04ODA1YTk5MjQ0YjBiOTk0IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiVG90YWwgdmlzaWJsZSBwaXhlbHM6IDIzNTkyOTZcXG5SZWQgZG9taW5hbnQ6IDQ4MzAwMCAoMjAuNSUpXFxuR3JlZW4gZG9taW5hbnQ6IDE1NiAoMC4wJSlcXG5XYXJtICh5ZWxsb3cvb3JhbmdlKTogMTAyOTY2MyAoNDMuNiUpXFxuTmV1dHJhbDogODg2OTAgKDMuOCUpXFxuXFxuQnJpZ2h0IG1ldGFsbGljIGhpZ2hsaWdodHM6IDE3MjIxOCAoNy4zJSlcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJJIHNlZSDigJQgdGhlIGdyZWVuIHBhbmVsIGlzbid0IHNob3dpbmcgdXAgd2VsbCBiZWNhdXNlIGl0J3MgYmVoaW5kIHRoZSBvYmplY3RzLiBUaGUgcmVkIGNsb3RoIGlzIGRvbWluYW50LiBMZXQgbWUgYWRqdXN0IHRoZSBncmVlbiBwYW5lbCB0byBiZSBtb3JlIHZpc2libGUgYW5kIGltcHJvdmUgdGhlIENvcm5lbGwgYm94IHBhbGV0dGUgYmFsYW5jZS4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgSU1QUk9WRSBDT1JORUxMIEJPWCBQQUxFVFRFIEJBTEFOQ0VcXG4jIFRoZSBncmVlbiBuZWVkcyB0byBiZSBtb3JlIHZpc2libGUgZmFjaW5nIHRoZSByZWRcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblxcbiMgTWFrZSB0aGUgZ3JlZW4gcGFuZWwgbGFyZ2VyIGFuZCBtb3JlIHByb21pbmVudCBvbiB0aGUgcmlnaHRcXG5ncmVlbl9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkdyZWVuUGFuZWxcXFwiXVxcbmdyZWVuX3BhbmVsLmxvY2F0aW9uID0gKDIuNSwgMS41LCAxLjgpXFxuZ3JlZW5fcGFuZWwucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDkwKSwgMCwgbWF0aC5yYWRpYW5zKDIwKSlcXG5ncmVlbl9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBNYWtlIHRoZSByZWQgcGFuZWwgbGFyZ2VyIHRvb1xcbnJlZF9wYW5lbCA9IGJweS5kYXRhLm9iamVjdHNbXFxcIlJlZFBhbmVsXFxcIl1cXG5yZWRfcGFuZWwubG9jYXRpb24gPSAoLTIuNSwgMS41LCAxLjgpXFxucmVkX3BhbmVsLnJvdGF0aW9uX2V1bGVyID0gKG1hdGgucmFkaWFucyg5MCksIDAsIG1hdGgucmFkaWFucygtMjApKVxcbnJlZF9wYW5lbC5zY2FsZSA9ICgzLjAsIDQuMCwgMSlcXG5icHkub3BzLm9iamVjdC50cmFuc2Zvcm1fYXBwbHkobG9jYXRpb249RmFsc2UsIHJvdGF0aW9uPVRydWUsIHNjYWxlPVRydWUpXFxuXFxuIyBCcmlnaHRlbiB0aGUgZ3JlZW4gcGFuZWwgbWF0ZXJpYWwgc2xpZ2h0bHkgc28gaXQgcmVhZHNcXG5tYXRfZ3JlZW5fcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fR3JlZW5QYW5lbFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fcGFuZWwubm9kZV90cmVlXFxuYnNkZiA9IG50Lm5vZGVzWydQcmluY2lwbGVkIEJTREYnXVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjA2LCAwLjI4LCAwLjA3LCAxLjApICAjIHNsaWdodGx5IGJyaWdodGVyIGdyZWVuXFxuXFxuIyBBbHNvIG1ha2UgdGhlIHJlZCBwYW5lbCBzbGlnaHRseSBicmlnaHRlclxcbm1hdF9yZWRfcGFuZWwgPSBicHkuZGF0YS5tYXRlcmlhbHNbXFxcIk1fUmVkUGFuZWxcXFwiXVxcbm50ID0gbWF0X3JlZF9wYW5lbC5ub2RlX3RyZWVcXG5ic2RmID0gbnQubm9kZXNbJ1ByaW5jaXBsZWQgQlNERiddXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNDIsIDAuMDYsIDAuMDUsIDEuMCkgICMgc2xpZ2h0bHkgYnJpZ2h0ZXIgcmVkXFxuXFxuIyBNYWtlIHRoZSBncmVlbiB2ZWx2ZXQgY2xvdGggYnJpZ2h0ZXIgdG9vXFxubWF0X2dyZWVuX3ZlbHZldCA9IGJweS5kYXRhLm1hdGVyaWFsc1tcXFwiTV9HcmVlblZlbHZldFxcXCJdXFxubnQgPSBtYXRfZ3JlZW5fdmVsdmV0Lm5vZGVfdHJlZVxcbmJzZGYgPSBudC5ub2Rlc1snUHJpbmNpcGxlZCBCU0RGJ11cXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC4wNywgMC4zNSwgMC4wOCwgMS4wKVxcblxcbiMgVXBkYXRlIHRoZSBjb2xvciByYW1wIGluIGdyZWVuIHZlbHZldFxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ1ZBTFRPUkdCJzpcXG4gICAgICAgIG5vZGUuY29sb3JfcmFtcC5lbGVtZW50c1swXS5jb2xvciA9ICgwLjA2LCAwLjMyLCAwLjA3LCAxLjApXFxuICAgICAgICBub2RlLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC4xMCwgMC40MCwgMC4xMCwgMS4wKVxcblxcbnByaW50KFxcXCJDb3JuZWxsIHBhbGV0dGUgYmFsYW5jZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtODFiMGY1MDUyYjZiNDk3NCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNvcm5lbGwgcGFsZXR0ZSBiYWxhbmNlZC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFF1aWNrIHJlbmRlciB0byBjaGVjayBjb2xvciBiYWxhbmNlXFxuc2NlbmUgPSBicHkuY29udGV4dC5zY2VuZVxcbnNjZW5lLmN5Y2xlcy5zYW1wbGVzID0gMjRcXG5zY2VuZS5yZW5kZXIuZmlsZXBhdGggPSBcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzYucG5nXFxcIlxcbmJweS5vcHMucmVuZGVyLnJlbmRlcih3cml0ZV9zdGlsbD1UcnVlKVxcblxcbmltZyA9IGJweS5kYXRhLmltYWdlcy5sb2FkKFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3Ni5wbmdcXFwiKVxcbncsIGggPSBpbWcuc2l6ZVswXSwgaW1nLnNpemVbMV1cXG5waXhlbHMgPSBsaXN0KGltZy5waXhlbHMpXFxuXFxuIyBDb2xvciBhbmFseXNpc1xcbnJlZF9jb3VudCA9IDBcXG5ncmVlbl9jb3VudCA9IDBcXG53YXJtX2NvdW50ID0gMFxcbnRvdGFsID0gMFxcblxcbmZvciBpIGluIHJhbmdlKDAsIGxlbihwaXhlbHMpLCA0KTpcXG4gICAgciwgZywgYiA9IHBpeGVsc1tpXSwgcGl4ZWxzW2krMV0sIHBpeGVsc1tpKzJdXFxuICAgIHRvdGFsICs9IDFcXG4gICAgYnJpZ2h0bmVzcyA9IChyICsgZyArIGIpIC8gM1xcbiAgICBcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBcXG4gICAgaWYgciA+IDAuMTUgYW5kIHIgPiBnICogMS41IGFuZCByID4gYiAqIDEuNTpcXG4gICAgICAgIHJlZF9jb3VudCArPSAxXFxuICAgIGVsaWYgZyA+IDAuMTIgYW5kIGcgPiByICogMS4yIGFuZCBnID4gYiAqIDEuMzpcXG4gICAgICAgIGdyZWVuX2NvdW50ICs9IDFcXG4gICAgZWxpZiByID4gMC4yIGFuZCBnID4gMC4xNSBhbmQgciA+IGIgKiAxLjM6XFxuICAgICAgICB3YXJtX2NvdW50ICs9IDFcXG5cXG5wcmludChmXFxcIlJlZCBkb21pbmFudDogezEwMCpyZWRfY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiR3JlZW4gZG9taW5hbnQ6IHsxMDAqZ3JlZW5fY291bnQvdG90YWw6LjFmfSVcXFwiKVxcbnByaW50KGZcXFwiV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHJpZ2h0IHNpZGUgc3BlY2lmaWNhbGx5IGZvciBncmVlblxcbnJpZ2h0X2dyZWVuID0gMFxcbnJpZ2h0X3RvdGFsID0gMFxcbmZvciB5IGluIHJhbmdlKGgpOlxcbiAgICBmb3IgeCBpbiByYW5nZSh3ICogMiAvLyAzLCB3KTpcXG4gICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgIHIsIGcsIGIgPSBwaXhlbHNbaWR4XSwgcGl4ZWxzW2lkeCsxXSwgcGl4ZWxzW2lkeCsyXVxcbiAgICAgICAgICAgIHJpZ2h0X3RvdGFsICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjI6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2dyZWVuICs9IDFcXG5wcmludChmXFxcIlJpZ2h0IHNpZGUgZ3JlZW46IHsxMDAqcmlnaHRfZ3JlZW4vcmlnaHRfdG90YWw6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC1hNGI3YzkxNWYyZGVlYjJiIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkIGRvbWluYW50OiAxNC4wJVxcbkdyZWVuIGRvbWluYW50OiAzLjglXFxuV2FybTogMzEuNCVcXG5SaWdodCBzaWRlIGdyZWVuOiA5LjglXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWY2ODZiZDAyMTA5ZDgxNCIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl9hcmVhX2FzX2ltYWdlIiwiYXJndW1lbnRzIjoie1wiYXJlYV91aV90eXBlXCI6IFwiVklFV18zRFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlmNjg2YmQwMjEwOWQ4MTQiLCJjb250ZW50IjoiIn0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6IlRoZSBncmVlbiBpcyBub3cgdmlzaWJsZS4gTGV0IG1lIGltcHJvdmUgdGhlIGNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgdG8gYmUgbW9yZSBwcm9wZXJseSByZWZsZWN0aXZlIChyYXktdHJhY2luZyBkZW1vIGNsYXNzaWMpLCBhbmQgYWRkIGEgZmV3IG1vcmUgcmVmaW5lbWVudHMuIExldCBtZSBhbHNvIG1ha2UgdGhlIFN1emFubmUgYnVzdCBsb29rIG1vcmUgbGlrZSBhIHByb3BlciBidXN0LiIsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hZDc1NTJmNDUwYTMwZWZjIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxuIyBJTVBST1ZFIENIRUNLRVJFRCBTUEhFUkU6IFRydWUgcmF5LXRyYWNpbmcgcmVmbGVjdGl2ZSBjaHJvbWVcXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fQ2hlY2tlcmVkU3BoZXJlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5mb3IgbiBpbiBsaXN0KG50Lm5vZGVzKTpcXG4gICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoMTAwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDYwMCwgMCkpXFxuXFxuIyBQZXJmZWN0IG1pcnJvciBjaHJvbWUgd2l0aCBjaGVja2VyIHBhdHRlcm5cXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjAyICAjIHZlcnkgcG9saXNoZWQsIGNhdGNoZXMgcmVmbGVjdGlvbnNcXG5cXG4jIENoZWNrZXIgcGF0dGVybiB1c2luZyB0ZXh0dXJlIGNvb3JkaW5hdGVcXG50ZXhfY29vcmQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDb29yZCcsICgtNDAwLCAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtMjAwLCAwKSlcXG5tYXBwaW5nLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gKDMuMCwgMy4wLCAzLjApXFxubnQubGlua3MubmV3KHRleF9jb29yZC5vdXRwdXRzWydHZW5lcmF0ZWQnXSwgbWFwcGluZy5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNoZWNrZXIgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhDaGVja2VyJywgKDAsIDApKVxcbmNoZWNrZXIuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSA4LjBcXG5udC5saW5rcy5uZXcobWFwcGluZy5vdXRwdXRzWydWZWN0b3InXSwgY2hlY2tlci5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbmNvbG9yX3JhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDApKVxcbm50LmxpbmtzLm5ldyhjaGVja2VyLm91dHB1dHNbJ0ZhYyddLCBjb2xvcl9yYW1wLmlucHV0c1snRmFjJ10pXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuMDIsIDAuMDIsIDAuMDIsIDEuMCkgICMgZGFyayBzcXVhcmVzXFxuY29sb3JfcmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzFdLmNvbG9yID0gKDAuOTUsIDAuOTUsIDAuOTUsIDEuMCkgICMgbGlnaHQgc3F1YXJlc1xcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuXFxucHJpbnQoXFxcIkNoZWNrZXJlZCBzcGhlcmUgbWF0ZXJpYWwgaW1wcm92ZWQgLSB0cnVlIHJlZmxlY3RpdmUgY2hyb21lLlxcXCIpXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIElNUFJPVkUgU1VaQU5ORTogQmV0dGVyIG1hcmJsZSB3aXRoIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyBmZWVsXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tYXQgPSBicHkuZGF0YS5tYXRlcmlhbHMuZ2V0KFxcXCJNX1N1emFubmVNYXJibGVcXFwiKVxcbm50ID0gbWF0Lm5vZGVfdHJlZVxcbmZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICBudC5ub2Rlcy5yZW1vdmUobilcXG5cXG5vdXRwdXQgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVPdXRwdXRNYXRlcmlhbCcsICg4MDAsIDApKVxcbmJzZGYgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCc2RmUHJpbmNpcGxlZCcsICg0MDAsIDApKVxcbmJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10uZGVmYXVsdF92YWx1ZSA9ICgwLjg4LCAwLjg1LCAwLjc4LCAxLjApICAjIHdhcm0gbWFyYmxlXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjI1XFxuYnNkZi5pbnB1dHNbJ1NwZWN1bGFyIElPUiBMZXZlbCddLmRlZmF1bHRfdmFsdWUgPSAwLjVcXG5cXG4jIE1hcmJsZSB2ZWluaW5nIHVzaW5nIG5vaXNlIGFuZCB3YXZlXFxudGV4X2Nvb3JkID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Q29vcmQnLCAoLTYwMCwgMTAwKSlcXG5tYXBwaW5nID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWFwcGluZycsICgtNDAwLCAxMDApKVxcbm1hcHBpbmcuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAoMS4wLCAzLjAsIDEuMClcXG5udC5saW5rcy5uZXcodGV4X2Nvb3JkLm91dHB1dHNbJ0dlbmVyYXRlZCddLCBtYXBwaW5nLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgtMjAwLCAyMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gMy4wXFxubm9pc2UuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDIuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCBub2lzZS5pbnB1dHNbJ1ZlY3RvciddKVxcblxcbndhdmUgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhXYXZlJywgKC0yMDAsIDEwMCkpXFxud2F2ZS5pbnB1dHNbJ1NjYWxlJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbndhdmUuaW5wdXRzWydEaXN0b3J0aW9uJ10uZGVmYXVsdF92YWx1ZSA9IDMuMFxcbm50LmxpbmtzLm5ldyhtYXBwaW5nLm91dHB1dHNbJ1ZlY3RvciddLCB3YXZlLmlucHV0c1snVmVjdG9yJ10pXFxuXFxubWl4ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlTWl4JywgKDAsIDEwMCkpXFxubWl4LmRhdGFfdHlwZSA9ICdSR0JBJ1xcbm50LmxpbmtzLm5ldyh3YXZlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbNl0pXFxubnQubGlua3MubmV3KG5vaXNlLm91dHB1dHNbJ0NvbG9yJ10sIG1peC5pbnB1dHNbN10pXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCBic2RmLmlucHV0c1snQmFzZSBDb2xvciddKVxcblxcbiMgQ29sb3IgcmFtcCBmb3IgdmVpbmluZ1xcbnJhbXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVWYWxUb1JHQicsICgyMDAsIDEwMCkpXFxubnQubGlua3MubmV3KG1peC5vdXRwdXRzWzJdLCByYW1wLmlucHV0c1snRmFjJ10pXFxucmFtcC5jb2xvcl9yYW1wLmVsZW1lbnRzWzBdLmNvbG9yID0gKDAuODUsIDAuODIsIDAuNzUsIDEuMClcXG5yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMV0uY29sb3IgPSAoMC40NSwgMC4zOCwgMC4zMCwgMS4wKVxcbm50LmxpbmtzLm5ldyhyYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuIyBTdWJ0bGUgYnVtcFxcbmJ1bXAgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVCdW1wJywgKDIwMCwgLTEwMCkpXFxuYnVtcC5pbnB1dHNbJ1N0cmVuZ3RoJ10uZGVmYXVsdF92YWx1ZSA9IDAuMDhcXG5ub2lzZTMgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAtMTAwKSlcXG5ub2lzZTMuaW5wdXRzWydTY2FsZSddLmRlZmF1bHRfdmFsdWUgPSAxMDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTMub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydCYXNlIENvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxubnQubGlua3MubmV3KGJ1bXAub3V0cHV0c1snTm9ybWFsJ10sIGJzZGYuaW5wdXRzWydOb3JtYWwnXSlcXG5cXG5udC5saW5rcy5uZXcoYnNkZi5vdXRwdXRzWydCU0RGJ10sIG91dHB1dC5pbnB1dHNbJ1N1cmZhY2UnXSlcXG5cXG5wcmludChcXFwiU3V6YW5uZSBtYXJibGUgbWF0ZXJpYWwgaW1wcm92ZWQuXFxcIilcXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWQ3NTUyZjQ1MGEzMGVmYyIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwiZXJyb3JcIixcbiAgXCJtZXNzYWdlXCI6IFwiVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOlxcbiAgRmlsZSBcXFwiQzpcXFxcVXNlcnNcXFxccHJvdWRcXFxcRG93bmxvYWRzXFxcXFRlbGVncmFtIERlc2t0b3BcXFxcYmxlbmRlci1iZW5jaC1ydW5uZXItd2luZG93c1xcXFwucnVubmVyXFxcXGJsZW5kZXItbWNwLXYxLjAuMFxcXFxhZGRvblxcXFxtY3BfdG9fYmxlbmRlcl9zZXJ2ZXIucHlcXFwiLCBsaW5lIDIzMCwgaW4gX2V4ZWN1dGVfY29kZVxcbiAgICBleGVjKGNvZGUsIG5hbWVzcGFjZSlcXG4gICAgfn5+fl5eXl5eXl5eXl5eXl5eXl5eXFxuICBGaWxlIFxcXCI8c3RyaW5nPlxcXCIsIGxpbmUgMTAzLCBpbiA8bW9kdWxlPlxcbktleUVycm9yOiAnYnB5X3Byb3BfY29sbGVjdGlvbltrZXldOiBrZXkgXFxcIkJhc2UgQ29sb3JcXFwiIG5vdCBmb3VuZCdcXG5cIixcbiAgXCJzdGRvdXRcIjogXCJDaGVja2VyZWQgc3BoZXJlIG1hdGVyaWFsIGltcHJvdmVkIC0gdHJ1ZSByZWZsZWN0aXZlIGNocm9tZS5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIFRoZSBCdW1wIG5vZGUgZG9lc24ndCBoYXZlICdCYXNlIENvbG9yJyBvdXRwdXQgLSBmaXggU3V6YW5uZSBtYXRlcmlhbFxcbm1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5nZXQoXFxcIk1fU3V6YW5uZU1hcmJsZVxcXCIpXFxubnQgPSBtYXQubm9kZV90cmVlXFxuXFxuIyBSZW1vdmUgdGhlIGJhZCBsaW5rXFxuZm9yIGxpbmsgaW4gbGlzdChudC5saW5rcyk6XFxuICAgIGlmICdCdW1wJyBpbiBsaW5rLmZyb21fbm9kZS5uYW1lIGFuZCBsaW5rLnRvX3NvY2tldC5uYW1lID09ICdCYXNlIENvbG9yJzpcXG4gICAgICAgIG50LmxpbmtzLnJlbW92ZShsaW5rKVxcbiAgICAgICAgcHJpbnQoZlxcXCJSZW1vdmVkIGJhZCBsaW5rIGZyb20ge2xpbmsuZnJvbV9ub2RlLm5hbWV9XFxcIilcXG5cXG4jIFZlcmlmeSB0aGUgbWF0ZXJpYWwgd29ya3NcXG5wcmludChcXFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXFwiKVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBwcmludChmXFxcIiAge25vZGUubmFtZX0gKHtub2RlLnR5cGV9KVxcXCIpXFxuICAgIFxcbnByaW50KFxcXCJcXFxcbkxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04OGZiMDdhY2E0NTI5ZWE2IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiU3V6YW5uZSBtYXRlcmlhbCBub2RlczpcXG4gIE1hdGVyaWFsIE91dHB1dCAoT1VUUFVUX01BVEVSSUFMKVxcbiAgUHJpbmNpcGxlZCBCU0RGIChCU0RGX1BSSU5DSVBMRUQpXFxuICBUZXh0dXJlIENvb3JkaW5hdGUgKFRFWF9DT09SRClcXG4gIE1hcHBpbmcgKE1BUFBJTkcpXFxuICBOb2lzZSBUZXh0dXJlIChURVhfTk9JU0UpXFxuICBXYXZlIFRleHR1cmUgKFRFWF9XQVZFKVxcbiAgTWl4IChNSVgpXFxuICBDb2xvciBSYW1wIChWQUxUT1JHQilcXG4gIEJ1bXAgKEJVTVApXFxuICBOb2lzZSBUZXh0dXJlLjAwMSAoVEVYX05PSVNFKVxcblxcbkxpbmtzOlxcbiAgVGV4dHVyZSBDb29yZGluYXRlLkdlbmVyYXRlZCAtPiBNYXBwaW5nLlZlY3RvclxcbiAgTWFwcGluZy5WZWN0b3IgLT4gTm9pc2UgVGV4dHVyZS5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IFdhdmUgVGV4dHVyZS5WZWN0b3JcXG4gIFdhdmUgVGV4dHVyZS5Db2xvciAtPiBNaXguQVxcbiAgTm9pc2UgVGV4dHVyZS5Db2xvciAtPiBNaXguQlxcbiAgTWl4LlJlc3VsdCAtPiBDb2xvciBSYW1wLkZhY3RvclxcbiAgQ29sb3IgUmFtcC5Db2xvciAtPiBQcmluY2lwbGVkIEJTREYuQmFzZSBDb2xvclxcbiAgTm9pc2UgVGV4dHVyZS4wMDEuRmFjdG9yIC0+IEJ1bXAuSGVpZ2h0XFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtOWNkZGNlZDE1OGExNmE3ZiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBDb25uZWN0IGJ1bXAgdG8gQlNERiBOb3JtYWwgYW5kIEJTREYgdG8gb3V0cHV0XFxubWF0ID0gYnB5LmRhdGEubWF0ZXJpYWxzLmdldChcXFwiTV9TdXphbm5lTWFyYmxlXFxcIilcXG5udCA9IG1hdC5ub2RlX3RyZWVcXG5cXG4jIE1ha2Ugc3VyZSBidW1wIG5vcm1hbCBnb2VzIHRvIEJTREZcXG5idW1wID0gTm9uZVxcbmJzZGYgPSBOb25lXFxub3V0cHV0ID0gTm9uZVxcbmZvciBub2RlIGluIG50Lm5vZGVzOlxcbiAgICBpZiBub2RlLnR5cGUgPT0gJ0JVTVAnOlxcbiAgICAgICAgYnVtcCA9IG5vZGVcXG4gICAgZWxpZiBub2RlLnR5cGUgPT0gJ0JTREZfUFJJTkNJUExFRCc6XFxuICAgICAgICBic2RmID0gbm9kZVxcbiAgICBlbGlmIG5vZGUudHlwZSA9PSAnT1VUUFVUX01BVEVSSUFMJzpcXG4gICAgICAgIG91dHB1dCA9IG5vZGVcXG5cXG5pZiBidW1wIGFuZCBic2RmOlxcbiAgICBudC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbiAgICBwcmludChcXFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXFwiKVxcblxcbmlmIGJzZGYgYW5kIG91dHB1dDpcXG4gICAgbnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuICAgIHByaW50KFxcXCJDb25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXFwiKVxcblxcbnByaW50KFxcXCJcXFxcbkZpbmFsIGxpbmtzOlxcXCIpXFxuZm9yIGxpbmsgaW4gbnQubGlua3M6XFxuICAgIHByaW50KGZcXFwiICB7bGluay5mcm9tX25vZGUubmFtZX0ue2xpbmsuZnJvbV9zb2NrZXQubmFtZX0gLT4ge2xpbmsudG9fbm9kZS5uYW1lfS57bGluay50b19zb2NrZXQubmFtZX1cXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05Y2RkY2VkMTU4YTE2YTdmIiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiQ29ubmVjdGVkIGJ1bXAgdG8gQlNERiBOb3JtYWxcXG5Db25uZWN0ZWQgQlNERiB0byBvdXRwdXRcXG5cXG5GaW5hbCBsaW5rczpcXG4gIFRleHR1cmUgQ29vcmRpbmF0ZS5HZW5lcmF0ZWQgLT4gTWFwcGluZy5WZWN0b3JcXG4gIE1hcHBpbmcuVmVjdG9yIC0+IE5vaXNlIFRleHR1cmUuVmVjdG9yXFxuICBNYXBwaW5nLlZlY3RvciAtPiBXYXZlIFRleHR1cmUuVmVjdG9yXFxuICBXYXZlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkFcXG4gIE5vaXNlIFRleHR1cmUuQ29sb3IgLT4gTWl4LkJcXG4gIE1peC5SZXN1bHQgLT4gQ29sb3IgUmFtcC5GYWN0b3JcXG4gIENvbG9yIFJhbXAuQ29sb3IgLT4gUHJpbmNpcGxlZCBCU0RGLkJhc2UgQ29sb3JcXG4gIE5vaXNlIFRleHR1cmUuMDAxLkZhY3RvciAtPiBCdW1wLkhlaWdodFxcbiAgQnVtcC5Ob3JtYWwgLT4gUHJpbmNpcGxlZCBCU0RGLk5vcm1hbFxcbiAgUHJpbmNpcGxlZCBCU0RGLkJTREYgLT4gTWF0ZXJpYWwgT3V0cHV0LlN1cmZhY2VcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kLCBTdXphbm5lIG1hdGVyaWFsIGlzIGZpeGVkLiBOb3cgbGV0IG1lIHJlbmRlciB0byBjaGVjayBldmVyeXRoaW5nIGxvb2tzIGdvb2QuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLWExYmRlODI5MDAwNTE1NjgiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbnNjZW5lID0gYnB5LmNvbnRleHQuc2NlbmVcXG5zY2VuZS5jeWNsZXMuc2FtcGxlcyA9IDMyXFxuc2NlbmUucmVuZGVyLmZpbGVwYXRoID0gXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc3LnBuZ1xcXCJcXG5icHkub3BzLnJlbmRlci5yZW5kZXIod3JpdGVfc3RpbGw9VHJ1ZSlcXG5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbnByaW50KFxcXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxcIilcXG5mb3IgZ3kgaW4gcmFuZ2UoMTApOlxcbiAgICByb3cgPSBcXFwiXFxcIlxcbiAgICBmb3IgZ3ggaW4gcmFuZ2UoMTApOlxcbiAgICAgICAgeDEgPSBneCAqIHcgLy8gMTBcXG4gICAgICAgIHgyID0gKGd4KzEpICogdyAvLyAxMFxcbiAgICAgICAgeTEgPSBneSAqIGggLy8gMTBcXG4gICAgICAgIHkyID0gKGd5KzEpICogaCAvLyAxMFxcbiAgICAgICAgYnJpZ2h0X3N1bSA9IDBcXG4gICAgICAgIGNvdW50ID0gMFxcbiAgICAgICAgZm9yIHkgaW4gcmFuZ2UoeTEsIHkyLCAyNSk6XFxuICAgICAgICAgICAgZm9yIHggaW4gcmFuZ2UoeDEsIHgyLCAyNSk6XFxuICAgICAgICAgICAgICAgIGlkeCA9ICh5ICogdyArIHgpICogNFxcbiAgICAgICAgICAgICAgICBpZiBpZHggKyAyIDwgbGVuKHBpeGVscyk6XFxuICAgICAgICAgICAgICAgICAgICBicmlnaHRfc3VtICs9IChwaXhlbHNbaWR4XSArIHBpeGVsc1tpZHgrMV0gKyBwaXhlbHNbaWR4KzJdKSAvIDNcXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IDFcXG4gICAgICAgIGJyaWdodCA9IGJyaWdodF9zdW0gLyBjb3VudCBpZiBjb3VudCA+IDAgZWxzZSAwXFxuICAgICAgICBpZiBicmlnaHQgPCAwLjA2OiByb3cgKz0gXFxcIiAgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjEyOiByb3cgKz0gXFxcIsK3IFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4yOiByb3cgKz0gXFxcIuKAoiBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMzogcm93ICs9IFxcXCLil4sgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjQ6IHJvdyArPSBcXFwi4pePIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC41OiByb3cgKz0gXFxcIuKWkyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNjU6IHJvdyArPSBcXFwi4paSIFxcXCJcXG4gICAgICAgIGVsc2U6IHJvdyArPSBcXFwi4paIIFxcXCJcXG4gICAgcHJpbnQoZlxcXCIgIFJvdyB7Z3l9OiB8e3Jvd318XFxcIilcXG5cXG5yZXN1bHQgPSB7XFxcInN0YXR1c1xcXCI6IFxcXCJva1xcXCJ9XFxuXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYTFiZGU4MjkwMDA1MTU2OCIsImNvbnRlbnQiOiJ7XG4gIFwic3RhdHVzXCI6IFwib2tcIixcbiAgXCJyZXN1bHRcIjoge1xuICAgIFwic3RhdHVzXCI6IFwib2tcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkJyaWdodG5lc3MgbWFwICgxMHgxMCBncmlkKTpcXG4gIFJvdyAwOiB8ICDCtyDCtyAgICAgICAgIMK3IMK3IMK3IHxcXG4gIFJvdyAxOiB84oCiIMK3ICAgICDCtyDigKIg4oCiIMK3IMK3ICAgfFxcbiAgUm93IDI6IHzCtyDigKIg4peLIOKAoiDCtyAgICAgICAgICAgfFxcbiAgUm93IDM6IHzilpMg4paSIOKXjyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNDogfOKWiCDilpIg4pePIMK3ICAgICAgICAgICAgIHxcXG4gIFJvdyA1OiB84paTIOKXjyDilpMg4pePIOKXjyDCtyAgICAgICAgIHxcXG4gIFJvdyA2OiB8ICDil48g4paSIOKWkiDilogg4paSIOKWkyDil4sg4oCiICAgfFxcbiAgUm93IDc6IHzil4sg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMgfFxcbiAgUm93IDg6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paSIOKWkiDilpIgfFxcbiAgUm93IDk6IHzilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIgfFxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLThiZjUwODFjMzdlZWJlYjYiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImFyZ3VtZW50cyI6IntcImFyZWFfdWlfdHlwZVwiOiBcIlZJRVdfM0RcIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC04YmY1MDgxYzM3ZWViZWI2IiwiY29udGVudCI6IiJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIG9mIHRoZSBpbWFnZSBmb3IgZ3JlZW5cXG5pbWcgPSBicHkuZGF0YS5pbWFnZXMubG9hZChcXFwiQzovdG1wL3N0aWxsX2xpZmVfcHJldmlldzcucG5nXFxcIilcXG53LCBoID0gaW1nLnNpemVbMF0sIGltZy5zaXplWzFdXFxucGl4ZWxzID0gbGlzdChpbWcucGl4ZWxzKVxcblxcbiMgRGV0YWlsZWQgY29sb3IgY2hlY2sgb24gdGhlIHJpZ2h0IHBvcnRpb25cXG5yZWRfY291bnQgPSAwXFxuZ3JlZW5fY291bnQgPSAwXFxud2FybV9jb3VudCA9IDBcXG50b3RhbCA9IDBcXG5cXG5mb3IgaSBpbiByYW5nZSgwLCBsZW4ocGl4ZWxzKSwgNCk6XFxuICAgIHIsIGcsIGIgPSBwaXhlbHNbaV0sIHBpeGVsc1tpKzFdLCBwaXhlbHNbaSsyXVxcbiAgICB0b3RhbCArPSAxXFxuICAgIGJyaWdodG5lc3MgPSAociArIGcgKyBiKSAvIDNcXG4gICAgaWYgYnJpZ2h0bmVzcyA8IDAuMDU6XFxuICAgICAgICBjb250aW51ZVxcbiAgICBpZiByID4gMC4xNSBhbmQgciA+IGcgKiAxLjUgYW5kIHIgPiBiICogMS41OlxcbiAgICAgICAgcmVkX2NvdW50ICs9IDFcXG4gICAgZWxpZiBnID4gMC4xIGFuZCBnID4gciAqIDEuMiBhbmQgZyA+IGIgKiAxLjM6XFxuICAgICAgICBncmVlbl9jb3VudCArPSAxXFxuICAgIGVsaWYgciA+IDAuMiBhbmQgZyA+IDAuMTUgYW5kIHIgPiBiICogMS4zOlxcbiAgICAgICAgd2FybV9jb3VudCArPSAxXFxuXFxucHJpbnQoZlxcXCJSZWQ6IHsxMDAqcmVkX2NvdW50L3RvdGFsOi4xZn0lLCBHcmVlbjogezEwMCpncmVlbl9jb3VudC90b3RhbDouMWZ9JSwgV2FybTogezEwMCp3YXJtX2NvdW50L3RvdGFsOi4xZn0lXFxcIilcXG5cXG4jIENoZWNrIHRoZSByaWdodCBzaWRlIHNwZWNpZmljYWxseVxcbnJpZ2h0X2cgPSAwXFxucmlnaHRfdCA9IDBcXG5mb3IgeSBpbiByYW5nZShoKTpcXG4gICAgZm9yIHggaW4gcmFuZ2UoaW50KHcqMC43KSwgdywgMyk6XFxuICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgIGlmIGlkeCArIDIgPCBsZW4ocGl4ZWxzKTpcXG4gICAgICAgICAgICByLCBnLCBiID0gcGl4ZWxzW2lkeF0sIHBpeGVsc1tpZHgrMV0sIHBpeGVsc1tpZHgrMl1cXG4gICAgICAgICAgICByaWdodF90ICs9IDFcXG4gICAgICAgICAgICBpZiBnID4gMC4wOCBhbmQgZyA+IHIgKiAxLjE1IGFuZCBnID4gYiAqIDEuMTU6XFxuICAgICAgICAgICAgICAgIHJpZ2h0X2cgKz0gMVxcbnByaW50KGZcXFwiUmlnaHQgc2lkZSBncmVlbjogezEwMCpyaWdodF9nL3JpZ2h0X3Q6LjFmfSVcXFwiKVxcblxcbnJlc3VsdCA9IHtcXFwic3RhdHVzXFxcIjogXFxcIm9rXFxcIn1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05NmYzYzAyMjU5ZjIyNjM4IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJzdGF0dXNcIjogXCJva1wiXG4gIH0sXG4gIFwic3Rkb3V0XCI6IFwiUmVkOiAxNC4wJSwgR3JlZW46IDMuOCUsIFdhcm06IDMxLjQlXFxuUmlnaHQgc2lkZSBncmVlbjogMTAuOCVcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOiJHb29kIC0gZ3JlZW4gaXMgbm93IHZpc2libGUgb24gdGhlIHJpZ2h0IHNpZGUuIFRoZSBjb21wb3NpdGlvbiBpcyB0YWtpbmcgc2hhcGUgd2l0aCByZWQgb24gdGhlIGxlZnQsIGdyZWVuIG9uIHRoZSByaWdodCAoQ29ybmVsbCBib3ggcGFsZXR0ZSksIHdhcm0gbGlnaHQsIGFuZCBkYXJrIHNoYWRvd3MuIExldCBtZSBub3cgYWRkIHNvbWUgZmluYWwgcG9saXNoOiBhIGNhbmRsZXN0aWNrIGFzIGFuIGFkZGl0aW9uYWwgY2xhc3NpY2FsIHByb3AgKHdoaWNoIGFsc28ganVzdGlmaWVzIHRoZSB3YXJtIGxpZ2h0IHNvdXJjZSksIGFuZCBtYWtlIGFkanVzdG1lbnRzIHRvIHRoZSBTdXphbm5lIGJ1c3QgcG9zaXRpb25pbmcuIiwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTk5Y2VkODg0NWIxOWNmNTciLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcbmltcG9ydCBibWVzaFxcbmltcG9ydCBtYXRoXFxuZnJvbSBtYXRodXRpbHMgaW1wb3J0IFZlY3RvclxcblxcbmRlZiBsaW5rX29iaihvYmopOlxcbiAgICBicHkuY29udGV4dC5zY2VuZS5jb2xsZWN0aW9uLm9iamVjdHMubGluayhvYmopXFxuICAgIHJldHVybiBvYmpcXG5cXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbiMgQ0FORExFU1RJQ0sgd2l0aCBjYW5kbGUgLSBhZGRpdGlvbmFsIGNsYXNzaWNhbCBwcm9wXFxuIyBKdXN0aWZpZXMgdGhlIHdhcm0gbGlnaHQgc291cmNlXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5tZXNoID0gYnB5LmRhdGEubWVzaGVzLm5ldyhcXFwiQ2FuZGxlc3RpY2tNZXNoXFxcIilcXG5ibSA9IGJtZXNoLm5ldygpXFxuXFxuIyBQcm9maWxlIG9mIHRoZSBjYW5kbGVzdGljayAocmFkaXVzLCBoZWlnaHQpIOKAlCBsYXRoZWRcXG5zdGlja19wcm9maWxlID0gW1xcbiAgICAoMC4wMCwgMC4wMCksICAgICMgY2VudGVyIGJvdHRvbVxcbiAgICAoMC4xMiwgMC4wMCksICAgICMgYmFzZSBlZGdlXFxuICAgICgwLjEzLCAwLjAxKSwgICAgIyBiYXNlIGxpcFxcbiAgICAoMC4xMiwgMC4wMyksICAgICMgXFxuICAgICgwLjA4LCAwLjA0KSwgICAgIyBiYXNlIHRvIHN0ZW1cXG4gICAgKDAuMDUsIDAuMDYpLCAgICAjIHN0ZW0gYmFzZVxcbiAgICAoMC4wNCwgMC4xNSksICAgICMgc3RlbVxcbiAgICAoMC4wNCwgMC4yNSksICAgICMgc3RlbVxcbiAgICAoMC4wNSwgMC4zMCksICAgICMgbWlkIGRlY29yYXRpdmVcXG4gICAgKDAuMDQsIDAuMzUpLCAgICAjIFxcbiAgICAoMC4wMzUsIDAuNDApLCAgICMgdXBwZXIgc3RlbVxcbiAgICAoMC4wNSwgMC40NCksICAgICMgY2FuZGxlIGN1cCBiYXNlXFxuICAgICgwLjA2LCAwLjQ2KSwgICAgIyBjdXBcXG4gICAgKDAuMDU1LCAwLjQ4KSwgICAjIGN1cCBsaXBcXG4gICAgKDAuMDQsIDAuNTApLCAgICAjIGN1cCBpbm5lclxcbiAgICAoMC4wMCwgMC41MCksICAgICMgY2VudGVyIHRvcFxcbl1cXG5cXG5zZWdtZW50cyA9IDQ4XFxuYWxsX3ZlcnRzID0gW11cXG5mb3IgciwgaCBpbiBzdGlja19wcm9maWxlOlxcbiAgICByaW5nID0gW11cXG4gICAgaWYgciA8IDAuMDAxOlxcbiAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoMCwgMCwgaCkpXFxuICAgICAgICByaW5nID0gW3ZdICogc2VnbWVudHNcXG4gICAgZWxzZTpcXG4gICAgICAgIGZvciBpIGluIHJhbmdlKHNlZ21lbnRzKTpcXG4gICAgICAgICAgICBhbmdsZSA9IChpIC8gc2VnbWVudHMpICogbWF0aC50YXVcXG4gICAgICAgICAgICB4ID0gciAqIG1hdGguY29zKGFuZ2xlKVxcbiAgICAgICAgICAgIHkgPSByICogbWF0aC5zaW4oYW5nbGUpXFxuICAgICAgICAgICAgdiA9IGJtLnZlcnRzLm5ldygoeCwgeSwgaCkpXFxuICAgICAgICAgICAgcmluZy5hcHBlbmQodilcXG4gICAgYWxsX3ZlcnRzLmFwcGVuZChyaW5nKVxcblxcbmJtLnZlcnRzLmVuc3VyZV9sb29rdXBfdGFibGUoKVxcblxcbmZvciByaSBpbiByYW5nZShsZW4oYWxsX3ZlcnRzKSAtIDEpOlxcbiAgICByaW5nX2EgPSBhbGxfdmVydHNbcmldXFxuICAgIHJpbmdfYiA9IGFsbF92ZXJ0c1tyaSArIDFdXFxuICAgIHJhLCBfID0gc3RpY2tfcHJvZmlsZVtyaV1cXG4gICAgcmIsIF8gPSBzdGlja19wcm9maWxlW3JpICsgMV1cXG4gICAgZm9yIGkgaW4gcmFuZ2Uoc2VnbWVudHMpOlxcbiAgICAgICAgaiA9IChpICsgMSkgJSBzZWdtZW50c1xcbiAgICAgICAgaWYgcmEgPCAwLjAwMTpcXG4gICAgICAgICAgICBibS5mYWNlcy5uZXcoW3JpbmdfYVtpXSwgcmluZ19iW2ldLCByaW5nX2Jbal1dKVxcbiAgICAgICAgZWxpZiByYiA8IDAuMDAxOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYVtqXV0pXFxuICAgICAgICBlbHNlOlxcbiAgICAgICAgICAgIGJtLmZhY2VzLm5ldyhbcmluZ19hW2ldLCByaW5nX2JbaV0sIHJpbmdfYltqXSwgcmluZ19hW2pdXSlcXG5cXG5ibS5ub3JtYWxfdXBkYXRlKClcXG5ibS50b19tZXNoKG1lc2gpXFxuYm0uZnJlZSgpXFxuXFxuc3RpY2tfb2JqID0gYnB5LmRhdGEub2JqZWN0cy5uZXcoXFxcIkNhbmRsZXN0aWNrXFxcIiwgbWVzaClcXG5saW5rX29iaihzdGlja19vYmopXFxuc3RpY2tfb2JqLmxvY2F0aW9uID0gKC0xLjYsIDAuOCwgMC4wKVxcbmJweS5jb250ZXh0LnZpZXdfbGF5ZXIub2JqZWN0cy5hY3RpdmUgPSBzdGlja19vYmpcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbm1vZCA9IHN0aWNrX29iai5tb2RpZmllcnMubmV3KFxcXCJTdWJzdXJmXFxcIiwgJ1NVQlNVUkYnKVxcbm1vZC5sZXZlbHMgPSAxXFxubW9kLnJlbmRlcl9sZXZlbHMgPSAyXFxuXFxuIyBDYW5kbGVcXG5icHkub3BzLm1lc2gucHJpbWl0aXZlX2N5bGluZGVyX2FkZChyYWRpdXM9MC4wMzUsIGRlcHRoPTAuMTUsIGxvY2F0aW9uPSgtMS42LCAwLjgsIDAuNTc1KSlcXG5jYW5kbGUgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuY2FuZGxlLm5hbWUgPSBcXFwiQ2FuZGxlXFxcIlxcbmJweS5vcHMub2JqZWN0LnNoYWRlX3Ntb290aCgpXFxuXFxuIyBDYW5kbGUgZmxhbWUgLSBhIHNtYWxsIGVtaXNzaXZlIHNoYXBlXFxuYnB5Lm9wcy5tZXNoLnByaW1pdGl2ZV91dl9zcGhlcmVfYWRkKHJhZGl1cz0wLjAzLCBzZWdtZW50cz0xNiwgcmluZ19jb3VudD04LCBsb2NhdGlvbj0oLTEuNiwgMC44LCAwLjcwKSlcXG5mbGFtZSA9IGJweS5jb250ZXh0LmFjdGl2ZV9vYmplY3RcXG5mbGFtZS5uYW1lID0gXFxcIkNhbmRsZUZsYW1lXFxcIlxcbmZsYW1lLnNjYWxlID0gKDAuNiwgMC42LCAxLjgpXFxuYnB5Lm9wcy5vYmplY3QudHJhbnNmb3JtX2FwcGx5KGxvY2F0aW9uPUZhbHNlLCByb3RhdGlvbj1GYWxzZSwgc2NhbGU9VHJ1ZSlcXG5icHkub3BzLm9iamVjdC5zaGFkZV9zbW9vdGgoKVxcblxcbnByaW50KFxcXCJDYW5kbGVzdGljayB3aXRoIGNhbmRsZSBhbmQgZmxhbWUgYnVpbHQuXFxcIilcXG5yZXN1bHQgPSB7XFxcImNhbmRsZXN0aWNrXFxcIjogc3RpY2tfb2JqLm5hbWUsIFxcXCJjYW5kbGVcXFwiOiBjYW5kbGUubmFtZSwgXFxcImZsYW1lXFxcIjogZmxhbWUubmFtZX1cXG5cIn0ifX1dfSx7InJvbGUiOiJ0b29sIiwidG9vbF9jYWxsX2lkIjoiY2hhdGNtcGwtdG9vbC05OWNlZDg4NDViMTljZjU3IiwiY29udGVudCI6IntcbiAgXCJzdGF0dXNcIjogXCJva1wiLFxuICBcInJlc3VsdFwiOiB7XG4gICAgXCJjYW5kbGVzdGlja1wiOiBcIkNhbmRsZXN0aWNrXCIsXG4gICAgXCJjYW5kbGVcIjogXCJDYW5kbGVcIixcbiAgICBcImZsYW1lXCI6IFwiQ2FuZGxlRmxhbWVcIlxuICB9LFxuICBcInN0ZG91dFwiOiBcIkNhbmRsZXN0aWNrIHdpdGggY2FuZGxlIGFuZCBmbGFtZSBidWlsdC5cXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC04NjI1MzczM2JiMDYwZDViIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImV4ZWN1dGVfYmxlbmRlcl9jb2RlIiwiYXJndW1lbnRzIjoie1wiY29kZVwiOiBcIlxcbmltcG9ydCBicHlcXG5pbXBvcnQgbWF0aFxcblxcbmRlZiBjcmVhdGVfbWF0ZXJpYWwobmFtZSk6XFxuICAgIG1hdCA9IGJweS5kYXRhLm1hdGVyaWFscy5uZXcobmFtZSlcXG4gICAgbWF0LnVzZV9ub2RlcyA9IFRydWVcXG4gICAgbnQgPSBtYXQubm9kZV90cmVlXFxuICAgIGZvciBuIGluIGxpc3QobnQubm9kZXMpOlxcbiAgICAgICAgbnQubm9kZXMucmVtb3ZlKG4pXFxuICAgIHJldHVybiBtYXQsIG50XFxuXFxuZGVmIGFkZF9ub2RlKG50LCBub2RlX3R5cGUsIGxvY2F0aW9uPSgwLDApKTpcXG4gICAgbiA9IG50Lm5vZGVzLm5ldyhub2RlX3R5cGUpXFxuICAgIG4ubG9jYXRpb24gPSBsb2NhdGlvblxcbiAgICByZXR1cm4gblxcblxcbiMgLS0tIENhbmRsZXN0aWNrOiBBZ2VkIGJyYXNzL2Jyb256ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZXN0aWNrQnJhc3NcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDYwMCwgMCkpXFxuYnNkZiA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJzZGZQcmluY2lwbGVkJywgKDMwMCwgMCkpXFxuYnNkZi5pbnB1dHNbJ0Jhc2UgQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDAuNTUsIDAuNDIsIDAuMjAsIDEuMCkgICMgYnJhc3NcXG5ic2RmLmlucHV0c1snTWV0YWxsaWMnXS5kZWZhdWx0X3ZhbHVlID0gMS4wXFxuYnNkZi5pbnB1dHNbJ1JvdWdobmVzcyddLmRlZmF1bHRfdmFsdWUgPSAwLjM1XFxuXFxuIyBQYXRpbmEgdmFyaWF0aW9uXFxubm9pc2UgPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVUZXhOb2lzZScsICgwLCAxMDApKVxcbm5vaXNlLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNS4wXFxubm9pc2UuaW5wdXRzWydEZXRhaWwnXS5kZWZhdWx0X3ZhbHVlID0gNC4wXFxuY29sb3JfcmFtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZVZhbFRvUkdCJywgKDEwMCwgMTAwKSlcXG5udC5saW5rcy5uZXcobm9pc2Uub3V0cHV0c1snRmFjJ10sIGNvbG9yX3JhbXAuaW5wdXRzWydGYWMnXSlcXG5jb2xvcl9yYW1wLmNvbG9yX3JhbXAuZWxlbWVudHNbMF0uY29sb3IgPSAoMC41NSwgMC40MiwgMC4yMCwgMS4wKSAgIyBicmFzc1xcbmNvbG9yX3JhbXAuY29sb3JfcmFtcC5lbGVtZW50c1sxXS5jb2xvciA9ICgwLjI1LCAwLjM1LCAwLjIwLCAxLjApICAjIHBhdGluYVxcbm50LmxpbmtzLm5ldyhjb2xvcl9yYW1wLm91dHB1dHNbJ0NvbG9yJ10sIGJzZGYuaW5wdXRzWydCYXNlIENvbG9yJ10pXFxuXFxuYnVtcCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZUJ1bXAnLCAoMTAwLCAtMTAwKSlcXG5idW1wLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMC4yXFxubm9pc2UyID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlVGV4Tm9pc2UnLCAoLTEwMCwgLTEwMCkpXFxubm9pc2UyLmlucHV0c1snU2NhbGUnXS5kZWZhdWx0X3ZhbHVlID0gNDAuMFxcbm50LmxpbmtzLm5ldyhub2lzZTIub3V0cHV0c1snRmFjJ10sIGJ1bXAuaW5wdXRzWydIZWlnaHQnXSlcXG5udC5saW5rcy5uZXcoYnVtcC5vdXRwdXRzWydOb3JtYWwnXSwgYnNkZi5pbnB1dHNbJ05vcm1hbCddKVxcbm50LmxpbmtzLm5ldyhic2RmLm91dHB1dHNbJ0JTREYnXSwgb3V0cHV0LmlucHV0c1snU3VyZmFjZSddKVxcblxcbmJweS5kYXRhLm9iamVjdHNbXFxcIkNhbmRsZXN0aWNrXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGU6IFdheGVkIG9mZi13aGl0ZSAtLS1cXG5tYXQsIG50ID0gY3JlYXRlX21hdGVyaWFsKFxcXCJNX0NhbmRsZVxcXCIpXFxub3V0cHV0ID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlT3V0cHV0TWF0ZXJpYWwnLCAoNDAwLCAwKSlcXG5ic2RmID0gYWRkX25vZGUobnQsICdTaGFkZXJOb2RlQnNkZlByaW5jaXBsZWQnLCAoMjAwLCAwKSlcXG5ic2RmLmlucHV0c1snQmFzZSBDb2xvciddLmRlZmF1bHRfdmFsdWUgPSAoMC44NSwgMC44MiwgMC43MiwgMS4wKVxcbmJzZGYuaW5wdXRzWydSb3VnaG5lc3MnXS5kZWZhdWx0X3ZhbHVlID0gMC41XFxubnQubGlua3MubmV3KGJzZGYub3V0cHV0c1snQlNERiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlXFxcIl0uZGF0YS5tYXRlcmlhbHMuYXBwZW5kKG1hdClcXG5cXG4jIC0tLSBDYW5kbGUgZmxhbWU6IEVtaXNzaXZlIC0tLVxcbm1hdCwgbnQgPSBjcmVhdGVfbWF0ZXJpYWwoXFxcIk1fQ2FuZGxlRmxhbWVcXFwiKVxcbm91dHB1dCA9IGFkZF9ub2RlKG50LCAnU2hhZGVyTm9kZU91dHB1dE1hdGVyaWFsJywgKDQwMCwgMCkpXFxuZW1pc3Npb24gPSBhZGRfbm9kZShudCwgJ1NoYWRlck5vZGVFbWlzc2lvbicsICgyMDAsIDApKVxcbmVtaXNzaW9uLmlucHV0c1snQ29sb3InXS5kZWZhdWx0X3ZhbHVlID0gKDEuMCwgMC43LCAwLjMsIDEuMCkgICMgd2FybSBmbGFtZVxcbmVtaXNzaW9uLmlucHV0c1snU3RyZW5ndGgnXS5kZWZhdWx0X3ZhbHVlID0gMTUuMFxcbm50LmxpbmtzLm5ldyhlbWlzc2lvbi5vdXRwdXRzWydFbWlzc2lvbiddLCBvdXRwdXQuaW5wdXRzWydTdXJmYWNlJ10pXFxuYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlRmxhbWVcXFwiXS5kYXRhLm1hdGVyaWFscy5hcHBlbmQobWF0KVxcblxcbiMgQWRkIGEgcG9pbnQgbGlnaHQgYXQgdGhlIGZsYW1lIGZvciBhY3R1YWwgaWxsdW1pbmF0aW9uXFxuYnB5Lm9wcy5vYmplY3QubGlnaHRfYWRkKHR5cGU9J1BPSU5UJywgbG9jYXRpb249KC0xLjYsIDAuOCwgMC43MikpXFxuZmxhbWVfbGlnaHQgPSBicHkuY29udGV4dC5hY3RpdmVfb2JqZWN0XFxuZmxhbWVfbGlnaHQubmFtZSA9IFxcXCJDYW5kbGVMaWdodFxcXCJcXG5mbGFtZV9saWdodC5kYXRhLmVuZXJneSA9IDUwXFxuZmxhbWVfbGlnaHQuZGF0YS5jb2xvciA9ICgxLjAsIDAuNywgMC4zKVxcbmZsYW1lX2xpZ2h0LmRhdGEuc2hhZG93X3NvZnRfc2l6ZSA9IDAuMDVcXG5cXG5wcmludChcXFwiQ2FuZGxlc3RpY2ssIGNhbmRsZSwgYW5kIGZsYW1lIG1hdGVyaWFscyBjcmVhdGVkLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg2MjUzNzMzYmIwNjBkNWIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJDYW5kbGVzdGljaywgY2FuZGxlLCBhbmQgZmxhbWUgbWF0ZXJpYWxzIGNyZWF0ZWQuXFxuXCJcbn0ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpudWxsLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtYWQyNzZmN2UwNDNiOGY4NiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuXFxuIyBSZW5kZXIgd2l0aCBjYW5kbGVcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3OC5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc4LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDEweDEwIGdyaWQpOlxcXCIpXFxuZm9yIGd5IGluIHJhbmdlKDEwKTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDEwKTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDEwXFxuICAgICAgICB4MiA9IChneCsxKSAqIHcgLy8gMTBcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDEwXFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gMTBcXG4gICAgICAgIGJyaWdodF9zdW0gPSAwXFxuICAgICAgICBjb3VudCA9IDBcXG4gICAgICAgIGZvciB5IGluIHJhbmdlKHkxLCB5MiwgMjUpOlxcbiAgICAgICAgICAgIGZvciB4IGluIHJhbmdlKHgxLCB4MiwgMjUpOlxcbiAgICAgICAgICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgICAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgICAgICAgICAgYnJpZ2h0X3N1bSArPSAocGl4ZWxzW2lkeF0gKyBwaXhlbHNbaWR4KzFdICsgcGl4ZWxzW2lkeCsyXSkgLyAzXFxuICAgICAgICAgICAgICAgICAgICBjb3VudCArPSAxXFxuICAgICAgICBicmlnaHQgPSBicmlnaHRfc3VtIC8gY291bnQgaWYgY291bnQgPiAwIGVsc2UgMFxcbiAgICAgICAgaWYgYnJpZ2h0IDwgMC4wNjogcm93ICs9IFxcXCIgIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4xMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40OiByb3cgKz0gXFxcIuKXjyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNTU6IHJvdyArPSBcXFwi4paTIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC43OiByb3cgKz0gXFxcIuKWkiBcXFwiXFxuICAgICAgICBlbHNlOiByb3cgKz0gXFxcIuKWiCBcXFwiXFxuICAgIHByaW50KGZcXFwiICBSb3cge2d5fTogfHtyb3d9fFxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLWFkMjc2ZjdlMDQzYjhmODYiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHRuZXNzIG1hcCAoMTB4MTAgZ3JpZCk6XFxuICBSb3cgMDogfCAgwrcgwrcgICAgICAgICDCtyDCtyDCtyB8XFxuICBSb3cgMTogfOKAoiDCtyAgICAgwrcg4oCiIOKAoiDCtyDCtyAgIHxcXG4gIFJvdyAyOiB8wrcg4oCiIOKXiyDigKIgwrcgICAgICAgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkyDil48gwrcgICAgICAgICAgICAgfFxcbiAgUm93IDQ6IHzilpIg4paSIOKWkyDCtyAgICAgICAgICAgICB8XFxuICBSb3cgNTogfOKWkyDil48g4paTIOKXjyDil48gwrcgICAgICAgICB8XFxuICBSb3cgNjogfCAg4pePIOKWkiDilpIg4paSIOKWkyDilpMg4peLIOKAoiAgIHxcXG4gIFJvdyA3OiB84pePIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpMg4paTIHxcXG4gIFJvdyA4OiB84paIIOKWiCDilogg4paIIOKWiCDilpIg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyA5OiB84paSIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paTIHxcXG5cIlxufSJ9LHsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOm51bGwsInRvb2xfY2FsbHMiOlt7ImlkIjoiY2hhdGNtcGwtdG9vbC1hYzY4Yzc1Y2I2Y2Q3NDMxIiwidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2UiLCJhcmd1bWVudHMiOiJ7XCJhcmVhX3VpX3R5cGVcIjogXCJWSUVXXzNEXCJ9In19XX0seyJyb2xlIjoidG9vbCIsInRvb2xfY2FsbF9pZCI6ImNoYXRjbXBsLXRvb2wtYWM2OGM3NWNiNmNkNzQzMSIsImNvbnRlbnQiOiIifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiVGhlIGNvbXBvc2l0aW9uIGlzIGxvb2tpbmcgZ29vZC4gTGV0IG1lIG1ha2Ugc29tZSBmaW5hbCBhZGp1c3RtZW50czogSSB3YW50IHRvIGVuc3VyZSB0aGUgdGFibGUgZWRnZSBpcyB2aXNpYmxlIGluIHRoZSBsb3dlciBmcmFtZSwgYW5kIHRoYXQgdGhlIG9iamVjdHMgYXJlIHdlbGwtZ3JvdXBlZCB3aXRoIG92ZXJsYXBwaW5nIGRlcHRoLiBMZXQgbWUgYWxzbyBhZGQgYSBmZXcgbW9yZSBkZXRhaWxzIHRvIHNlbGwgdGhlIER1dGNoIEdvbGRlbiBBZ2UgbG9vay4iLCJ0b29sX2NhbGxzIjpbeyJpZCI6ImNoYXRjbXBsLXRvb2wtODgwZTcyM2JlYTZmODFkMiIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZSIsImFyZ3VtZW50cyI6IntcImNvZGVcIjogXCJcXG5pbXBvcnQgYnB5XFxuaW1wb3J0IG1hdGhcXG5mcm9tIG1hdGh1dGlscyBpbXBvcnQgVmVjdG9yXFxuXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG4jIEZJTkFMIENPTVBPU0lUSU9OIEFESlVTVE1FTlRTXFxuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXG5cXG4jIEFkanVzdCBjYW1lcmEgdG8gc2VlIHRhYmxlIGVkZ2UgaW4gbG93ZXIgZnJhbWUgYW5kIGdldCBiZXR0ZXIgYW5nbGVcXG5jYW0gPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDYW1lcmFfUHJlc2VudGF0aW9uXFxcIl1cXG5jYW0ubG9jYXRpb24gPSAoMy4wLCAtMy41LCAxLjgpXFxudGFyZ2V0ID0gVmVjdG9yKCgwLjEsIC0wLjEsIDAuMykpXFxuZGlyZWN0aW9uID0gdGFyZ2V0IC0gY2FtLmxvY2F0aW9uXFxucm90X3F1YXQgPSBkaXJlY3Rpb24udG9fdHJhY2tfcXVhdCgnLVonLCAnWScpXFxuY2FtLnJvdGF0aW9uX2V1bGVyID0gcm90X3F1YXQudG9fZXVsZXIoKVxcbmNhbS5kYXRhLmRvZi5mb2N1c19kaXN0YW5jZSA9IChjYW0ubG9jYXRpb24gLSB0YXJnZXQpLmxlbmd0aFxcblxcbiMgQWRqdXN0IHRlYXBvdCBwb3NpdGlvbiB0byBiZSBtb3JlIGNlbnRlcmVkIGFuZCBjb21tYW5kaW5nXFxudGVhcG90ID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiVXRhaFRlYXBvdFxcXCJdXFxudGVhcG90LmxvY2F0aW9uID0gKDAuMCwgMC4wLCAwLjApXFxudGVhcG90LnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygtMTUpKVxcbnRlYXBvdC5zY2FsZSA9ICgwLjk1LCAwLjk1LCAwLjk1KVxcblxcbiMgQnVubnkgc2xpZ2h0bHkgY2xvc2VyIGFuZCB0dXJuZWQgdG93YXJkIGNhbWVyYVxcbmJ1bm55ID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiU3RhbmZvcmRCdW5ueVxcXCJdXFxuYnVubnkubG9jYXRpb24gPSAoLTEuMCwgMC4yLCAwLjAzKVxcbmJ1bm55LnJvdGF0aW9uX2V1bGVyID0gKDAsIG1hdGgucmFkaWFucyg1KSwgbWF0aC5yYWRpYW5zKDMwKSlcXG5idW5ueS5zY2FsZSA9ICgxLjE1LCAxLjE1LCAxLjE1KVxcblxcbiMgU3V6YW5uZSBvbiByaWdodCwgZ2F6aW5nIG91dFxcbnN1emFubmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lXFxcIl1cXG5zdXphbm5lLmxvY2F0aW9uID0gKDEuMCwgLTAuMSwgMC4yKVxcbnN1emFubmUucm90YXRpb25fZXVsZXIgPSAobWF0aC5yYWRpYW5zKDgpLCBtYXRoLnJhZGlhbnMoLTUpLCBtYXRoLnJhZGlhbnMoNzApKVxcbmJhc2UgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJTdXphbm5lQmFzZVxcXCJdXFxuYmFzZS5sb2NhdGlvbiA9IChzdXphbm5lLmxvY2F0aW9uLngsIHN1emFubmUubG9jYXRpb24ueSwgMC4wNClcXG5cXG4jIFNwaGVyZSBtb3JlIGNlbnRlcmVkLCBpbiBmcm9udCBvZiB0ZWFwb3RcXG5zcGhlcmUgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDaGVja2VyZWRTcGhlcmVcXFwiXVxcbnNwaGVyZS5sb2NhdGlvbiA9ICgwLjIsIC0wLjY1LCAwLjIyKVxcblxcbiMgV2luZSBnbGFzcyBtb3ZlZCBzbGlnaHRseVxcbmdsYXNzID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUdsYXNzXFxcIl1cXG5nbGFzcy5sb2NhdGlvbiA9ICgxLjY1LCAwLjQsIDAuMClcXG53aW5lID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiV2luZUxpcXVpZFxcXCJdXFxud2luZS5sb2NhdGlvbiA9IGdsYXNzLmxvY2F0aW9uLmNvcHkoKVxcblxcbiMgQ2FuZGxlc3RpY2sgb24gbGVmdCwgYmVoaW5kIGJ1bm55XFxuc3RpY2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDYW5kbGVzdGlja1xcXCJdXFxuc3RpY2subG9jYXRpb24gPSAoLTEuNywgMC45LCAwLjApXFxuY2FuZGxlID0gYnB5LmRhdGEub2JqZWN0c1tcXFwiQ2FuZGxlXFxcIl1cXG5jYW5kbGUubG9jYXRpb24gPSAoLTEuNywgMC45LCAwLjU3NSlcXG5mbGFtZSA9IGJweS5kYXRhLm9iamVjdHNbXFxcIkNhbmRsZUZsYW1lXFxcIl1cXG5mbGFtZS5sb2NhdGlvbiA9ICgtMS43LCAwLjksIDAuNzApXFxuZmxhbWVfbGlnaHQgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJDYW5kbGVMaWdodFxcXCJdXFxuZmxhbWVfbGlnaHQubG9jYXRpb24gPSAoLTEuNywgMC45LCAwLjcyKVxcblxcbiMgQm9va1xcbmJvb2sgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJPcGVuQm9va1xcXCJdXFxuYm9vay5sb2NhdGlvbiA9ICgtMC40LCAtMC44NSwgMC4wMilcXG5ib29rLnJvdGF0aW9uX2V1bGVyID0gKDAsIDAsIG1hdGgucmFkaWFucygyNSkpXFxuY292ZXIgPSBicHkuZGF0YS5vYmplY3RzW1xcXCJCb29rQ292ZXJcXFwiXVxcbmNvdmVyLmxvY2F0aW9uID0gYm9vay5sb2NhdGlvbi5jb3B5KClcXG5jb3Zlci5yb3RhdGlvbl9ldWxlciA9IGJvb2sucm90YXRpb25fZXVsZXIuY29weSgpXFxuXFxuIyBGcnVpdFxcbmJweS5kYXRhLm9iamVjdHNbXFxcIk9yYW5nZTFcXFwiXS5sb2NhdGlvbiA9ICgwLjgsIC0wLjg1LCAwLjA5KVxcbmJweS5kYXRhLm9iamVjdHNbXFxcIk9yYW5nZTJcXFwiXS5sb2NhdGlvbiA9ICgxLjAsIC0wLjc1LCAwLjA3NSlcXG5icHkuZGF0YS5vYmplY3RzW1xcXCJMZW1vbjFcXFwiXS5sb2NhdGlvbiA9ICgwLjY1LCAtMC43LCAwLjA4KVxcblxcbnByaW50KFxcXCJGaW5hbCBjb21wb3NpdGlvbiBhZGp1c3RtZW50cyBtYWRlLlxcXCIpXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTg4MGU3MjNiZWE2ZjgxZDIiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJGaW5hbCBjb21wb3NpdGlvbiBhZGp1c3RtZW50cyBtYWRlLlxcblwiXG59In0seyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6bnVsbCwidG9vbF9jYWxscyI6W3siaWQiOiJjaGF0Y21wbC10b29sLTlhYjIwNmNmZDhjNGJhNWQiLCJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJhcmd1bWVudHMiOiJ7XCJjb2RlXCI6IFwiXFxuaW1wb3J0IGJweVxcblxcbiMgUmVuZGVyIHByZXZpZXdcXG5zY2VuZSA9IGJweS5jb250ZXh0LnNjZW5lXFxuc2NlbmUuY3ljbGVzLnNhbXBsZXMgPSAzMlxcbnNjZW5lLnJlbmRlci5maWxlcGF0aCA9IFxcXCJDOi90bXAvc3RpbGxfbGlmZV9wcmV2aWV3OS5wbmdcXFwiXFxuYnB5Lm9wcy5yZW5kZXIucmVuZGVyKHdyaXRlX3N0aWxsPVRydWUpXFxuXFxuaW1nID0gYnB5LmRhdGEuaW1hZ2VzLmxvYWQoXFxcIkM6L3RtcC9zdGlsbF9saWZlX3ByZXZpZXc5LnBuZ1xcXCIpXFxudywgaCA9IGltZy5zaXplWzBdLCBpbWcuc2l6ZVsxXVxcbnBpeGVscyA9IGxpc3QoaW1nLnBpeGVscylcXG5cXG5wcmludChcXFwiQnJpZ2h0bmVzcyBtYXAgKDEyeDEyIGdyaWQpOlxcXCIpXFxuZm9yIGd5IGluIHJhbmdlKDEyKTpcXG4gICAgcm93ID0gXFxcIlxcXCJcXG4gICAgZm9yIGd4IGluIHJhbmdlKDEyKTpcXG4gICAgICAgIHgxID0gZ3ggKiB3IC8vIDEyXFxuICAgICAgICB4MiA9IChneCsxKSAqIHcgLy8gMTJcXG4gICAgICAgIHkxID0gZ3kgKiBoIC8vIDEyXFxuICAgICAgICB5MiA9IChneSsxKSAqIGggLy8gMTJcXG4gICAgICAgIGJyaWdodF9zdW0gPSAwXFxuICAgICAgICBjb3VudCA9IDBcXG4gICAgICAgIGZvciB5IGluIHJhbmdlKHkxLCB5MiwgMzApOlxcbiAgICAgICAgICAgIGZvciB4IGluIHJhbmdlKHgxLCB4MiwgMzApOlxcbiAgICAgICAgICAgICAgICBpZHggPSAoeSAqIHcgKyB4KSAqIDRcXG4gICAgICAgICAgICAgICAgaWYgaWR4ICsgMiA8IGxlbihwaXhlbHMpOlxcbiAgICAgICAgICAgICAgICAgICAgYnJpZ2h0X3N1bSArPSAocGl4ZWxzW2lkeF0gKyBwaXhlbHNbaWR4KzFdICsgcGl4ZWxzW2lkeCsyXSkgLyAzXFxuICAgICAgICAgICAgICAgICAgICBjb3VudCArPSAxXFxuICAgICAgICBicmlnaHQgPSBicmlnaHRfc3VtIC8gY291bnQgaWYgY291bnQgPiAwIGVsc2UgMFxcbiAgICAgICAgaWYgYnJpZ2h0IDwgMC4wNjogcm93ICs9IFxcXCIgIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC4xMjogcm93ICs9IFxcXCLCtyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuMjogcm93ICs9IFxcXCLigKIgXFxcIlxcbiAgICAgICAgZWxpZiBicmlnaHQgPCAwLjM6IHJvdyArPSBcXFwi4peLIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC40OiByb3cgKz0gXFxcIuKXjyBcXFwiXFxuICAgICAgICBlbGlmIGJyaWdodCA8IDAuNTU6IHJvdyArPSBcXFwi4paTIFxcXCJcXG4gICAgICAgIGVsaWYgYnJpZ2h0IDwgMC43OiByb3cgKz0gXFxcIuKWkiBcXFwiXFxuICAgICAgICBlbHNlOiByb3cgKz0gXFxcIuKWiCBcXFwiXFxuICAgIHByaW50KGZcXFwiICBSb3cge2d5fTogfHtyb3d9fFxcXCIpXFxuXFxucmVzdWx0ID0ge1xcXCJzdGF0dXNcXFwiOiBcXFwib2tcXFwifVxcblwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJ0b29sX2NhbGxfaWQiOiJjaGF0Y21wbC10b29sLTlhYjIwNmNmZDhjNGJhNWQiLCJjb250ZW50Ijoie1xuICBcInN0YXR1c1wiOiBcIm9rXCIsXG4gIFwicmVzdWx0XCI6IHtcbiAgICBcInN0YXR1c1wiOiBcIm9rXCJcbiAgfSxcbiAgXCJzdGRvdXRcIjogXCJCcmlnaHRuZXNzIG1hcCAoMTJ4MTIgZ3JpZCk6XFxuICBSb3cgMDogfMK3IMK3ICAgICAgIMK3IOKAoiDigKIg4oCiIOKAoiDCtyAgIHxcXG4gIFJvdyAxOiB84oCiICAgICDigKIg4peLIOKXiyDigKIgwrcgICAgICAgICB8XFxuICBSb3cgMjogfCAg4oCiIOKXjyDil4sg4oCiIMK3ICAgICAgICAgICAgIHxcXG4gIFJvdyAzOiB84paTIOKWkyDil4sgICAgICAgICAgICAgICAgICAgfFxcbiAgUm93IDQ6IHzilpIg4paSIOKXjyDigKIgICAgICAgICAgICAgICAgIHxcXG4gIFJvdyA1OiB84paSIOKWkiDilpMgwrcgwrcgICAgICAgICAgICAgICB8XFxuICBSb3cgNjogfOKWkiDilpMg4pePIOKXiyDigKIgICAgICAgICAgICAgICB8XFxuICBSb3cgNzogfOKXiyDil48g4paSIOKWkyDilogg4paSIOKXjyDigKIgwrcgICAgICAgfFxcbiAgUm93IDg6IHwgIOKWkiDilpIg4paSIOKWkiDilpIg4paTIOKWkiDilpMg4pePIOKXiyDCtyB8XFxuICBSb3cgOTogfOKWkyDilogg4paIIOKWiCDilogg4paSIOKWkiDilpIg4paSIOKWkiDilpIg4paTIHxcXG4gIFJvdyAxMDogfOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIOKWkiDilpIg4paSIHxcXG4gIFJvdyAxMTogfOKWiCDilogg4paIIOKWiCDilogg4paIIOKWiCDilogg4paIIOKWkiDilpIg4paSIHxcXG5cIlxufSJ9XSwidXNhZ2UiOnsiaW5jbHVkZSI6dHJ1ZX0sInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBFeGVjdXRlIFB5dGhvbiBjb2RlIGluIHRoZSBjb25uZWN0ZWQgQmxlbmRlciBpbnN0YW5jZS5cblxuICAgICAgICBUaGUgY29kZSBydW5zIGluIEJsZW5kZXIncyBQeXRob24gZW52aXJvbm1lbnQgd2l0aCBmdWxsIGFjY2VzcyB0byBgYGJweWBgLlxuICAgICAgICBUbyByZXR1cm4gZGF0YSwgYXNzaWduIGEgSlNPTi1zZXJpYWxpc2FibGUgZGljdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBgcmVzdWx0YGAuXG4gICAgICAgIERlZmVycmVkIGNvbXBsZXRpb24gdmlhIGBgY2hlY2tfaXNfZmluaXNoZWRgYCBpcyBvbmx5IHN1cHBvcnRlZCBieSB0aGVcbiAgICAgICAgaW50ZXJhY3RpdmUgYWRkb24gc2VydmVyLCBhbmQgaXMgcmVqZWN0ZWQgaW4gYmFja2dyb3VuZCBtb2RlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiY29kZSI6eyJ0aXRsZSI6IkNvZGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJleGVjdXRlX2JsZW5kZXJfY29kZV9mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgRXhlY3V0ZSBQeXRob24gY29kZSBpbiBhIGJhY2tncm91bmQgQmxlbmRlciBwcm9jZXNzLlxuXG4gICAgICAgIE9wZW5zICpibGVuZF9maWxlKiB3aXRoIGBgYmxlbmRlciAtLWJhY2tncm91bmRgYCBhbmQgcnVucyAqY29kZSouXG4gICAgICAgIEFzc2lnbiBhIGRpY3QgdG8gYGByZXN1bHRgYCB0byByZXR1cm4gZGF0YS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9LCJjb2RlIjp7InRpdGxlIjoiQ29kZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiLCJjb2RlIl0sInRpdGxlIjoiZXhlY3V0ZV9ibGVuZGVyX2NvZGVfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgc3VtbWFyeSBvZiB0aGUgYmxlbmQgZmlsZTogZGF0YS1ibG9jayBjb3VudHMsIGFjdGl2ZSB3b3Jrc3BhY2UsIGFuZCByZW5kZXIgZW5naW5lLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9kYXRhYmxvY2tzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X2RhdGFibG9ja3NfZm9yX2NsaSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIGRhdGEtYmxvY2sgc3VtbWFyeSBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfZGF0YWJsb2Nrc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXMiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgZXh0ZXJuYWwgZmlsZSByZWZlcmVuY2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBkaXNrXG4gICAgICAgIChpbWFnZXMsIGxpYnJhcmllcywgZm9udHMsIHNvdW5kcywgbW92aWUgY2xpcHMsIGNhY2hlcywgc2VxdWVuY2VzKS5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfbWlzc2luZ19maWxlc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9taXNzaW5nX2ZpbGVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXBvcnQgbWlzc2luZyBmaWxlIHJlZmVyZW5jZXMgYnkgb3BlbmluZyAqYmxlbmRfZmlsZSogaW4gYmFja2dyb3VuZCBCbGVuZGVyLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsiYmxlbmRfZmlsZSI6eyJ0aXRsZSI6IkJsZW5kIEZpbGUiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJibGVuZF9maWxlIl0sInRpdGxlIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X21pc3NpbmdfZmlsZXNfZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmV0dXJuIGEgdHJlZSBvZiBkaXJlY3RseSBhbmQgaW5kaXJlY3RseSBsaW5rZWQgbGlicmFyeSBmaWxlcy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7fSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9vZl9saW5rZWRfbGlicmFyaWVzX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gbGlua2VkLWxpYnJhcnkgaW5mbyBieSBvcGVuaW5nICpibGVuZF9maWxlKiBpbiBiYWNrZ3JvdW5kIEJsZW5kZXIuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJibGVuZF9maWxlIjp7InRpdGxlIjoiQmxlbmQgRmlsZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImJsZW5kX2ZpbGUiXSwidGl0bGUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfb2ZfbGlua2VkX2xpYnJhcmllc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X2JsZW5kZmlsZV9zdW1tYXJ5X3BhdGhfaW5mbyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFNpbXBsZS9mYXN0IGFjY2VzcyB0byB0aGUgYmxlbmQgZmlsZSdzIHBhdGgsIHNhdmUgc3RhdHVzLCBhZ2UsIGFuZCBiYWNrdXBzLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfYmxlbmRmaWxlX3N1bW1hcnlfcGF0aF9pbmZvX2Zvcl9jbGkiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gcGF0aCBpbmZvIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV9wYXRoX2luZm9fZm9yX2NsaUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzcyIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIEd1ZXNzIHRoZSBwcmltYXJ5IHVzZS1jYXNlcyBvZiB0aGUgY3VycmVudCBibGVuZCBmaWxlIChzY29yZWQgMC0xMDAgd2l0aCBjZXJ0YWludHkpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnt9LCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgR3Vlc3MgdXNlLWNhc2VzIGJ5IG9wZW5pbmcgKmJsZW5kX2ZpbGUqIGluIGJhY2tncm91bmQgQmxlbmRlci5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7ImJsZW5kX2ZpbGUiOnsidGl0bGUiOiJCbGVuZCBGaWxlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsiYmxlbmRfZmlsZSJdLCJ0aXRsZSI6ImdldF9ibGVuZGZpbGVfc3VtbWFyeV91c2FnZV9ndWVzc19mb3JfY2xpQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdF9kZXRhaWxfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIHN0cnVjdHVyZWQgc3VtbWFyeSBvZiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkgKm5hbWUqLlxuXG4gICAgICAgIEluY2x1ZGVzIHR5cGUsIHRyYW5zZm9ybXMsIHBhcmVudCwgY2hpbGRyZW4sIG1vZGlmaWVycywgY29uc3RyYWludHMsXG4gICAgICAgIG1hdGVyaWFscywgdmlzaWJpbGl0eSwgZGF0YS1ibG9jayBuYW1lLCBhbmQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJnZXRfb2JqZWN0X2RldGFpbF9zdW1tYXJ5QXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X29iamVjdHNfc3VtbWFyeSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiB0aGUgc2NlbmUncyBjb2xsZWN0aW9uIGhpZXJhcmNoeSBhbmQgdGhlaXIgb2JqZWN0cy5cblxuICAgICAgICBFYWNoIGNvbGxlY3Rpb24gbGlzdHMgaXRzIG9iamVjdHMgKG5hbWUsIHR5cGUsIHBhcmVudCwgZGF0YSBuYW1lLFxuICAgICAgICBzZWxlY3Rpb24sIHZpc2liaWxpdHkpIGFuZCBuZXN0ZWQgY2hpbGQgY29sbGVjdGlvbnMuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X29iamVjdHNfc3VtbWFyeUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6ImdldF9weXRob25fYXBpX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZXR1cm4gdGhlIEJsZW5kZXIgUHl0aG9uIEFQSSBkb2NzIGZvciAqaWRlbnRpZmllciosIG9yIGxpc3RcbiAgICAgICAgbW9kdWxlcyBtYXRjaGluZyBhIHRyYWlsaW5nLWBgKmBgIGRpc2NvdmVyeSBwYXR0ZXJuLlxuXG4gICAgICAgICppZGVudGlmaWVyKiBzaG91bGQgYmUgYSBmdWxseS1xdWFsaWZpZWQgUHl0aG9uIG5hbWUgKGUuZy5cbiAgICAgICAgYGBicHkuYXBwYGAgb3IgYGBicHkudHlwZXMuU2NlbmUuZnJhbWVfY3VycmVudGBgKS5cbiAgICAgICAgVGhlIHRyYWlsaW5nLWBgKmBgIGZvcm1zIGFyZSBzdXBwb3J0ZWQgYXMgZGlzY292ZXJ5IGVudHJ5LXBvaW50czpcblxuICAgICAgICAtIGBgKmBgIGVudW1lcmF0ZXMgdGhlIHRvcC1sZXZlbCBtb2R1bGVzIChgYGJweWBgLCBgYGJtZXNoYGAsXG4gICAgICAgICAgYGBtYXRodXRpbHNgYCwgYGBncHVgYCwgLi4uKS5cbiAgICAgICAgLSBgYFguKmBgIGVudW1lcmF0ZXMgdGhlIGRpcmVjdC1jaGlsZCBpZGVudGlmaWVycyB1bmRlciB0aGVcbiAgICAgICAgICAqWCogbmFtZXNwYWNlIChgYGJweS4qYGAgLT4gYGBicHkuYXBwYGAsIGBgYnB5LmNvbnRleHRgYCwgLi4uKS5cblxuICAgICAgICBCb3RoIHJldHVybiBhIGBgbmFtZXNwYWNlYGAgcmVzcG9uc2UgZXZlbiB3aGVuIGBgWC5yc3RgYCB3b3VsZFxuICAgICAgICBvdGhlcndpc2UgcmVzb2x2ZSB0byBgYGV4YWN0YGA7IHRoZSBgYC4qYGAgZm9ybSBsZXRzIGFuIGFnZW50XG4gICAgICAgIGZvcmNlIHRoZSBjaGlsZCBsaXN0aW5nLlxuXG4gICAgICAgIFRoZSByZXNwb25zZSBhbHdheXMgY2FycmllcyBgYGtpbmRgYCwgYGBmb3VuZGBgLCBhbmQgYGBpZGVudGlmaWVyYGAuXG4gICAgICAgIFRoZSByZW1haW5pbmcga2V5cyBkZXBlbmQgb24gYGBraW5kYGA6XG5cbiAgICAgICAgLSBgYFwiZXhhY3RcImBgIChgYGZvdW5kPVRydWVgYCk6IGBgPGlkZW50aWZpZXI+LnJzdGBgIHdhcyByZWFkLlxuICAgICAgICAgIEV4dHJhIGtleXM6IGBgY29udGVudGBgIChSU1QgdGV4dCksIGBgZXhhbXBsZXNgYC4gV2hlbiB0aGVcbiAgICAgICAgICBmaWxlIGV4Y2VlZHMgMzIgS0IsIGBgY29udGVudGBgIGlzIHJlcGxhY2VkIHdpdGggYSBkb3QtcG9pbnRcbiAgICAgICAgICBzdW1tYXJ5IG9mIHRoZSBmaWxlJ3MgdG9wLWxldmVsIGRlZmluaXRpb25zIChwcmVmaXhlZCBieSBhXG4gICAgICAgICAgaGVhZGVyIG5vdGluZyB0aGUgdHJ1bmNhdGlvbikgYW5kIGBgZXhhbXBsZXNgYCBpcyBlbXB0eSAtXG4gICAgICAgICAgcmUtcXVlcnkgaW5kaXZpZHVhbCBtZW1iZXJzIGZvciB0aGVpciByZW5kZXJlZCBibG9ja3MuXG4gICAgICAgIC0gYGBcIm5hbWVzcGFjZVwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICBubyBgYDxpZGVudGlmaWVyPi5yc3RgYCBidXQgYGA8aWRlbnRpZmllcj4uPGNoaWxkPi5yc3RgYCBzaWJsaW5ncyBleGlzdC5cbiAgICAgICAgICBFeHRyYSBrZXk6IGBgc3VibW9kdWxlc2BgIChsaXN0IG9mIGNoaWxkIGlkZW50aWZpZXJzKS5cbiAgICAgICAgLSBgYFwiZGVmaW5pdGlvblwiYGAgKGBgZm91bmQ9VHJ1ZWBgKTpcbiAgICAgICAgICAqaWRlbnRpZmllciogaXMgZGVmaW5lZCBpbnNpZGUgYSBwYXJlbnQgUlNUXG4gICAgICAgICAgKGUuZy4gYGBicHkucHJvcHMuSW50UHJvcGVydHlgYCBsaXZlcyBpbiBgYGJweS5wcm9wcy5yc3RgYCkuXG4gICAgICAgICAgRXh0cmEga2V5czogYGBjb250ZW50YGAgKHJlbmRlcmVkIGJsb2NrKSwgYGBleGFtcGxlc2BgLlxuICAgICAgICAtIGBgXCJwYXJ0aWFsXCJgYCAoYGBmb3VuZD1GYWxzZWBgKTpcbiAgICAgICAgICB0aGUgcGFyZW50IFJTVCB3YXMgbG9jYXRlZCBidXQgdGhlIHRyYWlsaW5nIGNvbXBvbmVudCBpc24ndCBkZWZpbmVkIGluIGl0LlxuICAgICAgICAgIEV4dHJhIGtleXM6XG4gICAgICAgICAgLSBgYHBhcmVudGBgIHRoZSBpZGVudGlmaWVyIHdob3NlIFJTVCB3YXMgbG9hZGVkLlxuICAgICAgICAgIC0gYGBhdmFpbGFibGVgYCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhhdCBSU1QuXG4gICAgICAgICAgLSBgYHN1Ym1vZHVsZXNgYCBzaWJsaW5nIGlkZW50aWZpZXJzIGBgPHBhcmVudD4uPGNoaWxkPmBgIHdpdGggdGhlaXIgb3duIFJTVHMsXG4gICAgICAgICAgICBmaWx0ZXJlZCB0byB0aG9zZSB3aG9zZSBsYXN0IGNvbXBvbmVudCBjb250YWlucyBldmVyeSBjaGFyYWN0ZXIgb2YgdGhlIG1pc3NpbmcgdGFpbC5cblxuICAgICAgICAgIEZvciBhIHRvY3RyZWUgbGFuZGluZyBwYWdlIGxpa2UgYGBicHkudHlwZXNgYCBgYGF2YWlsYWJsZWBgIGlzIGVtcHR5IGFuZCBgYHN1Ym1vZHVsZXNgYFxuICAgICAgICAgIGlzIHRoZSBuZWFyLW1pc3MgbGlzdDsgZm9yIGEgc2VsZi1jb250YWluZWQgbW9kdWxlIGxpa2UgYGBicHkucHJvcHNgYCBpdCdzIHRoZSByZXZlcnNlLlxuICAgICAgICAtIGBgXCJzdWdnZXN0aW9uc1wiYGAgKGBgZm91bmQ9RmFsc2VgYCk6XG4gICAgICAgICAgbm8gZGlyZWN0IG1hdGNoLCBidXQgKmlkZW50aWZpZXIqIGFwcGVhcnMgYXMgYSBjb21wb25lbnQgb2Ygb3RoZXIgZmlsZXMuXG4gICAgICAgICAgRXh0cmEga2V5OiBgYHN1Z2dlc3Rpb25zYGAgKGxpc3Qgb2YgZnVsbCBpZGVudGlmaWVycykuXG4gICAgICAgIC0gYGBcIm1pc3NpbmdcImBgIChgYGZvdW5kPUZhbHNlYGApOiBub3RoaW5nIG1hdGNoZWQuXG5cbiAgICAgICAgYGBleGFtcGxlc2BgIChwcmVzZW50IG9uIHRoZSBgYGV4YWN0YGAgYW5kIGBgZGVmaW5pdGlvbmBgIGtpbmRzKVxuICAgICAgICBpcyBhIGxpc3Qgb2YgYGB7cGF0aCwgY29udGVudH1gYCBlbnRyaWVzIHJlZmVyZW5jZWQgZnJvbSB0aGlzIGRvY3VtZW50YXRpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJpZGVudGlmaWVyIjp7InRpdGxlIjoiSWRlbnRpZmllciIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImlkZW50aWZpZXIiXSwidGl0bGUiOiJnZXRfcHl0aG9uX2FwaV9kb2NzQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiZ2V0X3NjcmVlbnNob3Rfb2ZfYXJlYV9hc19pbWFnZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFRha2UgYSBzY3JlZW5zaG90IG9mIGEgc2luZ2xlIEJsZW5kZXIgYXJlYSBhbmQgcmV0dXJuIGl0IGFzIGEgUE5HIGltYWdlLlxuXG4gICAgICAgICphcmVhX3VpX3R5cGUqIG1hdGNoZXMgdGhlIGFyZWEncyBgYHVpX3R5cGVgYC5cblxuICAgICAgICAqc2l6ZV9saW1pdF9pbl9ieXRlcyogY2FwcyB0aGUgaW1hZ2Ugc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgWmVybyAodGhlIGRlZmF1bHQpIHVzZXMgdGhlIE1DUCBtZXNzYWdlIHNpemUgbGltaXQuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJhcmVhX3VpX3R5cGUiOnsiZW51bSI6WyJWSUVXXzNEIiwiSU1BR0VfRURJVE9SIiwiVVYiLCJTaGFkZXJOb2RlVHJlZSIsIkNvbXBvc2l0b3JOb2RlVHJlZSIsIkdlb21ldHJ5Tm9kZVRyZWUiLCJUZXh0dXJlTm9kZVRyZWUiLCJTRVFVRU5DRV9FRElUT1IiLCJDTElQX0VESVRPUiIsIkRPUEVTSEVFVF9FRElUT1IiLCJHUkFQSF9FRElUT1IiLCJOTEFfRURJVE9SIiwiVEVYVF9FRElUT1IiLCJDT05TT0xFIiwiSU5GTyIsIlRPUEJBUiIsIlNUQVRVU0JBUiIsIk9VVExJTkVSIiwiUFJPUEVSVElFUyIsIkZJTEVfQlJPV1NFUiIsIlNQUkVBRFNIRUVUIiwiUFJFRkVSRU5DRVMiXSwidGl0bGUiOiJBcmVhIFVpIFR5cGUiLCJ0eXBlIjoic3RyaW5nIn0sInNpemVfbGltaXRfaW5fYnl0ZXMiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJTaXplIExpbWl0IEluIEJ5dGVzIiwidHlwZSI6ImludGVnZXIifX0sInJlcXVpcmVkIjpbImFyZWFfdWlfdHlwZSJdLCJ0aXRsZSI6ImdldF9zY3JlZW5zaG90X29mX2FyZWFfYXNfaW1hZ2VBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJnZXRfc2NyZWVuc2hvdF9vZl93aW5kb3dfYXNfanNvbiIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFJldHVybiBhIEpTT04gZGVzY3JpcHRpb24gb2YgdGhlIEJsZW5kZXIgd2luZG93IGxheW91dCwgYXJlYXMsIGFjdGl2ZSBvYmplY3QsIGFuZCBzZWxlY3Rpb24uXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6e30sInRpdGxlIjoiZ2V0X3NjcmVlbnNob3Rfb2Zfd2luZG93X2FzX2pzb25Bcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgU3dpdGNoIHRoZSBhY3RpdmUgd29ya3NwYWNlIHRhYiB0byAqbmFtZSouXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJuYW1lIjp7InRpdGxlIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3RhYl9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoianVtcF90b190YWJfYnlfc3BhY2VfdHlwZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIFN3aXRjaCB0byBhIHdvcmtzcGFjZSB3aG9zZSBtYWluIGFyZWEgbWF0Y2hlcyAqc3BhY2VfdHlwZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIGFuZCBubyBtYXRjaGluZyB3b3Jrc3BhY2UgZXhpc3RzLCBhIG5ldyBvbmVcbiAgICAgICAgaXMgY3JlYXRlZCBieSBkdXBsaWNhdGluZyB0aGUgY3VycmVudCB3b3Jrc3BhY2UuXG4gICAgICAgICIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJzcGFjZV90eXBlIjp7InRpdGxlIjoiU3BhY2UgVHlwZSIsInR5cGUiOiJzdHJpbmcifSwiYWxsb3dfZWRpdHMiOnsiZGVmYXVsdCI6ZmFsc2UsInRpdGxlIjoiQWxsb3cgRWRpdHMiLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsic3BhY2VfdHlwZSJdLCJ0aXRsZSI6Imp1bXBfdG9fdGFiX2J5X3NwYWNlX3R5cGVBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZSIsImRlc2NyaXB0aW9uIjoiXG4gICAgICAgIE1vdmUgdGhlIDNEIHZpZXdwb3J0IHRvIGZvY3VzIG9uIGFuIG9iamVjdCBieSAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfYnlfbmFtZUFyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19LHsidHlwZSI6ImZ1bmN0aW9uIiwiZnVuY3Rpb24iOnsibmFtZSI6Imp1bXBfdG9fdmlldzNkX29iamVjdF9kYXRhX2J5X25hbWUiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBNb3ZlIHRoZSAzRCB2aWV3cG9ydCB0byB0aGUgb2JqZWN0IHdob3NlIGRhdGEgYmxvY2sgbWF0Y2hlcyAqbmFtZSouXG5cbiAgICAgICAgSWYgKmFsbG93X2VkaXRzKiBpcyBUcnVlIHRoZSBvYmplY3QgbWF5IGJlIHVuLWhpZGRlbiBhbmQgaXRzXG4gICAgICAgIGNvbGxlY3Rpb25zIGVuYWJsZWQgdG8gbWFrZSBpdCB2aXNpYmxlLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsibmFtZSI6eyJ0aXRsZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn0sImFsbG93X2VkaXRzIjp7ImRlZmF1bHQiOmZhbHNlLCJ0aXRsZSI6IkFsbG93IEVkaXRzIiwidHlwZSI6ImJvb2xlYW4ifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidGl0bGUiOiJqdW1wX3RvX3ZpZXczZF9vYmplY3RfZGF0YV9ieV9uYW1lQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoIiwiZGVzY3JpcHRpb24iOiJcbiAgICAgICAgUmVuZGVyIGEgc21hbGwsIGxvdy1xdWFsaXR5IHRodW1ibmFpbCB0byAqb3V0cHV0X3BhdGgqICh0ZW1wb3JhcmlseSBvdmVycmlkZXMgc2V0dGluZ3MpLlxuICAgICAgICAiLCJwYXJhbWV0ZXJzIjp7InByb3BlcnRpZXMiOnsib3V0cHV0X3BhdGgiOnsidGl0bGUiOiJPdXRwdXQgUGF0aCIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm91dHB1dF9wYXRoIl0sInRpdGxlIjoicmVuZGVyX3RodW1ibmFpbF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoicmVuZGVyX3ZpZXdwb3J0X3RvX3BhdGgiLCJkZXNjcmlwdGlvbiI6IlxuICAgICAgICBSZW5kZXIgdGhlIGN1cnJlbnQgc2NlbmUgdG8gKm91dHB1dF9wYXRoKiB1c2luZyBjdXJyZW50IHJlbmRlciBzZXR0aW5ncy5cbiAgICAgICAgIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7Im91dHB1dF9wYXRoIjp7InRpdGxlIjoiT3V0cHV0IFBhdGgiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJvdXRwdXRfcGF0aCJdLCJ0aXRsZSI6InJlbmRlcl92aWV3cG9ydF90b19wYXRoQXJndW1lbnRzIiwidHlwZSI6Im9iamVjdCJ9fX0seyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoic2VhcmNoX2FwaV9kb2NzIiwiZGVzY3JpcHRpb24iOiJcbkZ1bGwtdGV4dCBzZWFyY2ggb3ZlciB0aGUgYnVuZGxlZCBCbGVuZGVyIFB5dGhvbiBBUEkgcmVmZXJlbmNlLlxuXG5SZXR1cm5zIGEgcmFua2VkIGxpc3Qgb2YgaGl0cy4gRWFjaCBoaXQgaGFzOlxuXG4tIGBgcGF0aGBgOiBmaWxlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJ1bmRsZWQgZG9jcy5cbi0gYGB0ZXh0YGA6IHRoZSBtYXRjaGluZyBwYXJhZ3JhcGggcGx1cyBgYGNvbnRleHRgYFxuICBwYXJhZ3JhcGhzIG9uIGVpdGhlciBzaWRlLlxuLSBgYGJyZWFkY3J1bWJgYDogdGhlIHNlY3Rpb24gcGF0aCBjb250YWluaW5nIHRoZSBoaXRcbiAgKGBgU2VjdGlvbiA+IFN1Yi1zZWN0aW9uID4gLi4uYGApLlxuLSBgYGluZGV4YGA6IHRoZSBoaXQncyBwb3NpdGlvbiBpbiB0aGUgcmVzdWx0IGxpc3QuXG4tIGBgc2NvcmVgYDogYSByZWxldmFuY2Ugc2NvcmU7IGhpZ2hlciBpcyBiZXR0ZXIuXG5cblRoZSBxdWVyeSBpcyB0b2tlbmlzZWQgb24gd2hpdGVzcGFjZSBhbmQgbWF0Y2hlZFxuY2FzZS1pbnNlbnNpdGl2ZWx5LiBFdmVyeSB0b2tlbiBtdXN0IGFwcGVhciBzb21ld2hlcmUgaW5cbnRoZSBwYXJhZ3JhcGggYm9keSwgdGhlIGZpbGUgcGF0aCwgb3IgYW4gZW5jbG9zaW5nIHNlY3Rpb25cbnRpdGxlIC0gaW4gYW55IG9yZGVyLiBDb21tb24gRW5nbGlzaCBzdG9wLXdvcmRzIChgYHRoZWBgLFxuYGBhYGAsIGBgaG93YGAsIGBgdG9gYCwgLi4uKSBhcmUgZHJvcHBlZCwgc28gbmF0dXJhbFxucGhyYXNpbmdzIGxpa2UgYGBcImhvdyB0byBiYWtlXCJgYCB3b3JrIGFzIGV4cGVjdGVkLiBSZWd1bGFyXG5leHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZC5cblxuVXNlIGBgY29udGV4dGBgIHRvIHB1bGwgbW9yZSBzdXJyb3VuZGluZyBwYXJhZ3JhcGhzIGludG9cbmVhY2ggaGl0IChzeW1tZXRyaWMsIGRlZmF1bHQgMCkuIFVzZSBgYGluZGV4YGAgd2l0aCB0aGVcbnBvc2l0aW9uIG9mIGEgcHJldmlvdXMgaGl0IChzYW1lIHF1ZXJ5KSB0byBnZXQgdGhhdCBoaXRcbmFsb25lIHdpdGggaXRzIHRleHQgd2lkZW5lZCB0byBpdHMgZW5jbG9zaW5nIHNlY3Rpb24uXG5cblJlYWQtb25seTsgY29uc3VsdHMgYnVuZGxlZCBSU1QgZmlsZXMgb25seS5cbiIsInBhcmFtZXRlcnMiOnsicHJvcGVydGllcyI6eyJxdWVyeSI6eyJ0aXRsZSI6IlF1ZXJ5IiwidHlwZSI6InN0cmluZyJ9LCJtYXhfcmVzdWx0cyI6eyJkZWZhdWx0IjoyMCwidGl0bGUiOiJNYXggUmVzdWx0cyIsInR5cGUiOiJpbnRlZ2VyIn0sImNvbnRleHQiOnsiZGVmYXVsdCI6MCwidGl0bGUiOiJDb250ZXh0IiwidHlwZSI6ImludGVnZXIifSwiaW5kZXgiOnsiYW55T2YiOlt7InR5cGUiOiJpbnRlZ2VyIn0seyJ0eXBlIjoibnVsbCJ9XSwiZGVmYXVsdCI6bnVsbCwidGl0bGUiOiJJbmRleCJ9fSwicmVxdWlyZWQiOlsicXVlcnkiXSwidGl0bGUiOiJzZWFyY2hfYXBpX2RvY3NBcmd1bWVudHMiLCJ0eXBlIjoib2JqZWN0In19fSx7InR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJzZWFyY2hfbWFudWFsX2RvY3MiLCJkZXNjcmlwdGlvbiI6IlxuRnVsbC10ZXh0IHNlYXJjaCBvdmVyIHRoZSBidW5kbGVkIEJsZW5kZXIgdXNlciBtYW51YWwuXG5cblJldHVybnMgYSByYW5rZWQgbGlzdCBvZiBoaXRzLiBFYWNoIGhpdCBoYXM6XG5cbi0gYGBwYXRoYGA6IGZpbGUgcGF0aCByZWxhdGl2ZSB0byB0aGUgYnVuZGxlZCBkb2NzLlxuLSBgYHRleHRgYDogdGhlIG1hdGNoaW5nIHBhcmFncmFwaCBwbHVzIGBgY29udGV4dGBgXG4gIHBhcmFncmFwaHMgb24gZWl0aGVyIHNpZGUuXG4tIGBgYnJlYWRjcnVtYmBgOiB0aGUgc2VjdGlvbiBwYXRoIGNvbnRhaW5pbmcgdGhlIGhpdFxuICAoYGBTZWN0aW9uID4gU3ViLXNlY3Rpb24gPiAuLi5gYCkuXG4tIGBgaW5kZXhgYDogdGhlIGhpdCdzIHBvc2l0aW9uIGluIHRoZSByZXN1bHQgbGlzdC5cbi0gYGBzY29yZWBgOiBhIHJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIGJldHRlci5cblxuVGhlIHF1ZXJ5IGlzIHRva2VuaXNlZCBvbiB3aGl0ZXNwYWNlIGFuZCBtYXRjaGVkXG5jYXNlLWluc2Vuc2l0aXZlbHkuIEV2ZXJ5IHRva2VuIG11c3QgYXBwZWFyIHNvbWV3aGVyZSBpblxudGhlIHBhcmFncmFwaCBib2R5LCB0aGUgZmlsZSBwYXRoLCBvciBhbiBlbmNsb3Npbmcgc2VjdGlvblxudGl0bGUgLSBpbiBhbnkgb3JkZXIuIENvbW1vbiBFbmdsaXNoIHN0b3Atd29yZHMgKGBgdGhlYGAsXG5gYGFgYCwgYGBob3dgYCwgYGB0b2BgLCAuLi4pIGFyZSBkcm9wcGVkLCBzbyBuYXR1cmFsXG5waHJhc2luZ3MgbGlrZSBgYFwiaG93IHRvIGJha2VcImBgIHdvcmsgYXMgZXhwZWN0ZWQuIFJlZ3VsYXJcbmV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5Vc2UgYGBjb250ZXh0YGAgdG8gcHVsbCBtb3JlIHN1cnJvdW5kaW5nIHBhcmFncmFwaHMgaW50b1xuZWFjaCBoaXQgKHN5bW1ldHJpYywgZGVmYXVsdCAwKS4gVXNlIGBgaW5kZXhgYCB3aXRoIHRoZVxucG9zaXRpb24gb2YgYSBwcmV2aW91cyBoaXQgKHNhbWUgcXVlcnkpIHRvIGdldCB0aGF0IGhpdFxuYWxvbmUgd2l0aCBpdHMgdGV4dCB3aWRlbmVkIHRvIGl0cyBlbmNsb3Npbmcgc2VjdGlvbi5cblxuUmVhZC1vbmx5OyBjb25zdWx0cyBidW5kbGVkIFJTVCBmaWxlcyBvbmx5LlxuIiwicGFyYW1ldGVycyI6eyJwcm9wZXJ0aWVzIjp7InF1ZXJ5Ijp7InRpdGxlIjoiUXVlcnkiLCJ0eXBlIjoic3RyaW5nIn0sIm1heF9yZXN1bHRzIjp7ImRlZmF1bHQiOjIwLCJ0aXRsZSI6Ik1heCBSZXN1bHRzIiwidHlwZSI6ImludGVnZXIifSwiY29udGV4dCI6eyJkZWZhdWx0IjowLCJ0aXRsZSI6IkNvbnRleHQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJpbmRleCI6eyJhbnlPZiI6W3sidHlwZSI6ImludGVnZXIifSx7InR5cGUiOiJudWxsIn1dLCJkZWZhdWx0IjpudWxsLCJ0aXRsZSI6IkluZGV4In19LCJyZXF1aXJlZCI6WyJxdWVyeSJdLCJ0aXRsZSI6InNlYXJjaF9tYW51YWxfZG9jc0FyZ3VtZW50cyIsInR5cGUiOiJvYmplY3QifX19XX0="}, "response": {"status_code": 403, "headers": {"date": "Fri, 17 Jul 2026 15:21:37 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "access-control-allow-origin": "*", "access-control-expose-headers": "X-Generation-Id,X-Provider-Name,cf-ray", "set-cookie": "[REDACTED]", "permissions-policy": "payment=(self \"https://checkout.stripe.com\" \"https://connect-js.stripe.com\" \"https://js.stripe.com\" \"https://*.js.stripe.com\" \"https://hooks.stripe.com\")", "referrer-policy": "no-referrer, strict-origin-when-cross-origin", "x-content-type-options": "nosniff", "content-encoding": "gzip", "server": "cloudflare", "cf-ray": "a1ca3cc80db203c7-MAD"}, "body": "{\"error\":{\"message\":\"Key limit exceeded (monthly limit). Manage it using https://openrouter.ai/workspaces/default/keys/1a374774f3a7af7618312f341536449f96173db9d74ce029ecae473c44b119e6\",\"code\":403}}", "body_base64": "eyJlcnJvciI6eyJtZXNzYWdlIjoiS2V5IGxpbWl0IGV4Y2VlZGVkIChtb250aGx5IGxpbWl0KS4gTWFuYWdlIGl0IHVzaW5nIGh0dHBzOi8vb3BlbnJvdXRlci5haS93b3Jrc3BhY2VzL2RlZmF1bHQva2V5cy8xYTM3NDc3NGYzYTdhZjc2MTgzMTJmMzQxNTM2NDQ5Zjk2MTczZGI5ZDc0Y2UwMjllY2FlNDczYzQ0YjExOWU2IiwiY29kZSI6NDAzfX0="}, "error": null}], "response": null, "error": {"type": "blenderbench.providers.openrouter.ProviderError", "message": "HTTP 403: {\"error\":{\"message\":\"Key limit exceeded (monthly limit). Manage it using https://openrouter.ai/workspaces/default/keys/1a374774f3a7af7618312f341536449f96173db9d74ce029ecae473c44b119e6\",\"code\":403}}", "repr": "ProviderError('HTTP 403: {\"error\":{\"message\":\"Key limit exceeded (monthly limit). Manage it using https://openrouter.ai/workspaces/default/keys/1a374774f3a7af7618312f341536449f96173db9d74ce029ecae473c44b119e6\",\"code\":403}}')"}}
{"ts": "2026-07-17T15:21:37.174979+00:00", "type": "status", "status": "model_error", "done_declared": false}
